1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
21 //----------------------------------------------------------------------------
22 //------------------- Linux Sources of OSD_FileNode --------------------------
23 //----------------------------------------------------------------------------
29 #include <Standard_ProgramError.hxx>
30 #include <OSD_OSDError.hxx>
31 #include <Standard_NullObject.hxx>
32 #include <OSD_WhoAmI.hxx>
33 #include <OSD_FileNode.ixx>
35 #if!defined(TM_IN_SYS_TIME) && defined(HAVE_TIME_H)
38 # include <sys/time.h>
41 #ifdef HAVE_SYS_TYPES_H
42 # include <sys/types.h>
45 #ifdef HAVE_SYS_STAT_H
46 # include <sys/stat.h> // for "stat"
49 #include <stdlib.h> // For "system"
64 const OSD_WhoAmI Iam = OSD_WFileNode;
67 // Create a file/directory object
69 OSD_FileNode::OSD_FileNode ()
73 // Create and initialize a file/directory object
75 OSD_FileNode::OSD_FileNode (const OSD_Path& Name)
82 // Get values of object
84 void OSD_FileNode::Path (OSD_Path& Name)const{
91 // Set values of object
93 void OSD_FileNode::SetPath (const OSD_Path& Name){
101 // Test if specified file/directory exists
103 Standard_Boolean OSD_FileNode::Exists(){
107 // if (myPath.Name().Length()==0) A directory can have a null name field (ex: root)
108 // OSD_OSDError::Raise("OSD_FileNode::Exists : no name was given"); (LD)
110 // if (Failed()) Perror();
112 TCollection_AsciiString aBuffer;
113 myPath.SystemName ( aBuffer );
114 status = access ( aBuffer.ToCString() , F_OK );
116 if (status == 0) return (Standard_True);
117 else return ( Standard_False );
123 // Physically remove a file/directory
125 void OSD_FileNode::Remove(){
127 // if (myPath.Name().Length()==0) A directory can have a null name field (ex: root)
128 // OSD_OSDError::Raise("OSD_FileNode::Remove : no name was given"); (LD)
130 // if (Failed()) Perror();
132 TCollection_AsciiString aBuffer;
133 myPath.SystemName ( aBuffer );
135 if(access(aBuffer.ToCString(), W_OK))
137 myError.SetValue (errno, Iam, "Remove");
141 struct stat stat_buf;
143 if(stat(aBuffer.ToCString(), &stat_buf))
145 myError.SetValue (errno, Iam, "Remove");
149 if ( S_ISDIR(stat_buf.st_mode)) {
152 if(rmdir(aBuffer.ToCString()))
154 myError.SetValue (errno, Iam, "Remove");
160 else if ( S_ISREG(stat_buf.st_mode) || S_ISLNK(stat_buf.st_mode) ||
161 S_ISFIFO(stat_buf.st_mode) ) {
163 if (unlink ( aBuffer.ToCString()) == -1)
164 myError.SetValue (errno, Iam, "Remove");
167 myError.SetValue (EINVAL, Iam, "Remove");
174 // Move a file/directory to another path
176 void OSD_FileNode::Move(const OSD_Path& NewPath){
178 TCollection_AsciiString thisPath;
180 // if (myPath.Name().Length()==0)
181 // OSD_OSDError::Raise("OSD_FileNode::Move : no name was given");
183 // if (Failed()) Perror();
185 NewPath.SystemName( thisPath ); // Get internal path name
186 TCollection_AsciiString aBuffer;
187 myPath.SystemName ( aBuffer );
188 status = rename (aBuffer.ToCString(), thisPath.ToCString());
190 if (status == -1) myError.SetValue (errno, Iam, "Move");
193 // Copy a file to another path and name
194 int static copy_file( const char* src, const char* trg )
198 int fds = open( src, O_RDONLY );
202 int fdo = open( trg, O_WRONLY|O_TRUNC| O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
210 const int BUFSIZE=4096;
213 while ( ( n = read ( fds, buf, BUFSIZE )) >0 )
215 if ( write ( fdo, buf, n ) != n ) { // writing error
230 void OSD_FileNode::Copy(const OSD_Path& ToPath)
233 TCollection_AsciiString second_name;
235 // if (myPath.Name().Length()==0) Copy .login would raise !!
236 // OSD_OSDError::Raise("OSD_FileNode::Copy : no name was given");
237 // if (Failed()) Perror();
239 ToPath.SystemName (second_name);
241 TCollection_AsciiString aBuffer;
242 myPath.SystemName ( aBuffer );
243 status = copy_file(aBuffer.ToCString(), second_name.ToCString());
244 if (status != 0) myError.SetValue (-1, Iam, "Copy failed") ;// (LD)
246 printf("Status %d : errno # %d\n",status,errno);
254 // Get protections of a file/directory
256 OSD_Protection OSD_FileNode::Protection(){
257 OSD_Protection thisProt;
262 // if (myPath.Name().Length()==0)
263 // OSD_OSDError::Raise("OSD_FileNode::Protection : no name was given");
265 // if (Failed()) Perror();
267 TCollection_AsciiString aBuffer;
268 myPath.SystemName ( aBuffer );
269 status = stat(aBuffer.ToCString(), &myStat);
270 if (status == -1) myError.SetValue (errno, Iam, "Protection");
272 u = g = w = OSD_None;
274 if (myStat.st_mode & S_IRUSR) u |= OSD_R;
275 if (myStat.st_mode & S_IWUSR) u |= OSD_W;
276 if (myStat.st_mode & S_IXUSR) u |= OSD_X;
278 if (myStat.st_mode & S_IRGRP) g |= OSD_R;
279 if (myStat.st_mode & S_IWGRP) g |= OSD_W;
280 if (myStat.st_mode & S_IXGRP) g |= OSD_X;
282 if (myStat.st_mode & S_IROTH) w |= OSD_R;
283 if (myStat.st_mode & S_IWOTH) w |= OSD_W;
284 if (myStat.st_mode & S_IXOTH) w |= OSD_X;
287 thisProt.SetValues ((OSD_SingleProtection)s,
288 (OSD_SingleProtection)u,
289 (OSD_SingleProtection)g,
290 (OSD_SingleProtection)w);
296 // Set protections of a file/directory
298 void OSD_FileNode::SetProtection(const OSD_Protection& Prot){
301 // if (myPath.Name().Length()==0)
302 // OSD_OSDError::Raise("OSD_FileNode::SetProtection : no name was given");
304 // if (Failed()) Perror();
306 TCollection_AsciiString aBuffer;
307 myPath.SystemName ( aBuffer );
308 status = chmod (aBuffer.ToCString(), (mode_t)Prot.Internal() );
309 if (status == -1) myError.SetValue (errno, Iam, "SetProtection");
316 Standard_Integer OSD_FileNode::UserId(){
319 // if (myPath.Name().Length()==0)
320 // OSD_OSDError::Raise("OSD_FileNode::UserId : no name was given");
322 // if (Failed()) Perror();
324 /* Get File Informations */
326 TCollection_AsciiString aBuffer;
327 myPath.SystemName ( aBuffer );
328 stat ( aBuffer.ToCString(), &buffer );
330 return ( buffer.st_uid );
336 Standard_Integer OSD_FileNode::GroupId(){
339 // if (myPath.Name().Length()==0)
340 // OSD_OSDError::Raise("OSD_FileNode::GroupId : no name was given");
342 // if (Failed()) Perror();
344 /* Get File Informations */
346 TCollection_AsciiString aBuffer;
347 myPath.SystemName ( aBuffer );
348 stat ( aBuffer.ToCString(), &buffer );
350 return ( buffer.st_gid );
356 // return the date of last access of file/directory
358 Quantity_Date OSD_FileNode::CreationMoment(){
360 Quantity_Date result;
364 // if (myPath.Name().Length()==0)
365 // OSD_OSDError::Raise("OSD_FileNode::CreationMoment : no name was given");
367 // if (Failed()) Perror();
369 /* Get File Informations */
371 TCollection_AsciiString aBuffer;
372 myPath.SystemName ( aBuffer );
373 if (!stat ( aBuffer.ToCString(), &buffer )) {
374 decode = localtime(&buffer.st_ctime);
376 decode->tm_mon+1, decode->tm_mday, decode->tm_year+1900,
377 decode->tm_hour, decode->tm_min, decode->tm_sec , 0,0);
380 result.SetValues (1, 1, 1979, 0, 0, 0, 0, 0) ;
384 // return Last access of file/directory
386 Quantity_Date OSD_FileNode::AccessMoment(){
388 Quantity_Date result;
392 // if (myPath.Name().Length()==0)
393 // OSD_OSDError::Raise("OSD_FileNode::AccessMoment : no name was given");
395 // if (Failed()) Perror();
397 /* Get File Informations */
399 TCollection_AsciiString aBuffer;
400 myPath.SystemName ( aBuffer );
401 if (!stat ( aBuffer.ToCString(), &buffer )) {
402 decode = localtime(&buffer.st_atime);
404 decode->tm_mon+1, decode->tm_mday, decode->tm_year+1900,
405 decode->tm_hour, decode->tm_min, decode->tm_sec, 0,0 );
408 result.SetValues (1, 1, 1979, 0, 0, 0, 0, 0) ;
413 void OSD_FileNode::Reset(){
417 Standard_Boolean OSD_FileNode::Failed()const{
418 return( myError.Failed());
421 void OSD_FileNode::Perror() {
426 Standard_Integer OSD_FileNode::Error()const{
427 return( myError.Error());
432 //----------------------------------------------------------------------------
433 //------------------- WNT Sources of OSD_FileNode ---------------------------
434 //----------------------------------------------------------------------------
437 #include <OSD_FileNode.hxx>
438 #include <OSD_Protection.hxx>
439 #include <Quantity_Date.hxx>
440 #include <Standard_ProgramError.hxx>
442 #include <OSD_WNT_1.hxx>
448 #define TEST_RAISE( arg ) _test_raise ( fName, ( arg ) )
449 #define RAISE( arg ) Standard_ProgramError :: Raise ( ( arg ) )
451 PSECURITY_DESCRIPTOR __fastcall _osd_wnt_protection_to_sd ( const OSD_Protection&, BOOL, char* = NULL );
452 BOOL __fastcall _osd_wnt_sd_to_protection (
453 PSECURITY_DESCRIPTOR pSD, OSD_Protection& prot, BOOL
455 Standard_Integer __fastcall _get_file_type ( Standard_CString, HANDLE );
457 void _osd_wnt_set_error ( OSD_Error&, OSD_WhoAmI, ... );
459 static BOOL __fastcall _get_file_time ( Standard_CString, LPSYSTEMTIME, BOOL );
460 static void __fastcall _test_raise ( TCollection_AsciiString, Standard_CString );
462 //=======================================================================
463 //function : OSD_FileNode
464 //purpose : Empty Constructor
465 //=======================================================================
467 OSD_FileNode::OSD_FileNode ()
471 //=======================================================================
472 //function : OSD_FileNode
473 //purpose : Constructor
474 //=======================================================================
476 OSD_FileNode::OSD_FileNode ( const OSD_Path& Name )
479 } // end constructor ( 2 )
481 //=======================================================================
484 //=======================================================================
486 void OSD_FileNode::Path ( OSD_Path& Name ) const {
490 } // end OSD_FileNode :: Path
492 //=======================================================================
495 //=======================================================================
497 void OSD_FileNode::SetPath ( const OSD_Path& Name ) {
501 } // end OSD_FileNode :: SetPath
503 //=======================================================================
506 //=======================================================================
508 Standard_Boolean OSD_FileNode::Exists () {
510 Standard_Boolean retVal = Standard_False;;
511 TCollection_AsciiString fName;
513 myPath.SystemName ( fName );
515 if ( fName.IsEmpty () ) return Standard_False;
516 TEST_RAISE( TEXT( "Exists" ) );
518 if ( GetFileAttributes ( fName.ToCString () ) == 0xFFFFFFFF ) {
520 if ( GetLastError () != ERROR_FILE_NOT_FOUND )
522 _osd_wnt_set_error ( myError, OSD_WFileNode, fName.ToCString () );
526 retVal = Standard_True;
530 } // end OSD_FileNode :: Exists
532 //=======================================================================
535 //=======================================================================
537 void OSD_FileNode::Remove () {
539 TCollection_AsciiString fName;
541 myPath.SystemName ( fName );
543 TEST_RAISE( TEXT( "Remove" ) );
545 switch (_get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE)) {
549 if ( !DeleteFile ( fName.ToCString () ) )
551 _osd_wnt_set_error ( myError, OSD_WFileNode, fName.ToCString () );
558 // LD : Suppression de l'appel a DeleteDirectory pour
559 // ne pas detruire un repertoire no vide.
561 if ( !RemoveDirectory ( fName.ToCString () ) )
563 _osd_wnt_set_error ( myError, OSD_WFileNode, fName.ToCString () );
569 RAISE( TEXT( "OSD_FileNode :: Remove ():"
570 " invalid file type - neither file nor directory" ) );
574 } // end OSD_FileNode :: Remove
576 //=======================================================================
579 //=======================================================================
581 void OSD_FileNode::Move ( const OSD_Path& NewPath ) {
583 TCollection_AsciiString fName;
584 TCollection_AsciiString fNameDst;
586 myPath.SystemName ( fName );
588 TEST_RAISE( TEXT( "Move" ) );
590 NewPath.SystemName ( fNameDst );
592 switch (_get_file_type (fName.ToCString (), INVALID_HANDLE_VALUE)) {
596 if (!MoveFileEx (fName.ToCString (), fNameDst.ToCString (),
597 MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED
601 _osd_wnt_set_error ( myError, OSD_WFileNode,
602 fName.ToCString (), fNameDst.ToCString () );
607 if ( !MoveDirectory (
608 fName.ToCString (), fNameDst.ToCString ()
612 _osd_wnt_set_error ( myError, OSD_WFileNode,
613 fName.ToCString (), fNameDst.ToCString () );
619 RAISE( TEXT( "OSD_FileNode :: Move (): "
620 "invalid file type - neither file nor directory" ) );
624 } // end OSD_FileNode :: Move
626 //=======================================================================
629 //=======================================================================
631 void OSD_FileNode::Copy ( const OSD_Path& ToPath ) {
633 TCollection_AsciiString fName;
634 TCollection_AsciiString fNameDst;
636 myPath.SystemName ( fName );
638 TEST_RAISE( TEXT( "Copy" ) );
640 ToPath.SystemName ( fNameDst );
642 switch (_get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE)) {
646 if (!CopyFile (fName.ToCString (), fNameDst.ToCString (), FALSE ))
647 _osd_wnt_set_error (myError, OSD_WFileNode,
648 fName.ToCString (), fNameDst.ToCString ());
653 if ( !CopyDirectory (
654 fName.ToCString (), fNameDst.ToCString ()
659 myError, OSD_WFileNode, fName.ToCString (), fNameDst.ToCString ()
666 RAISE( TEXT( "OSD_FileNode :: Copy ():"
667 " invalid file type - neither file nor directory" ) );
671 } // end OSD_FileNode :: Copy
673 //=======================================================================
674 //function : Protection
676 //=======================================================================
678 OSD_Protection OSD_FileNode::Protection () {
680 OSD_Protection retVal;
681 TCollection_AsciiString fName;
682 PSECURITY_DESCRIPTOR pSD;
684 myPath.SystemName ( fName );
686 TEST_RAISE( TEXT( "Protection" ) );
688 if ( ( pSD = GetFileSecurityEx (
689 fName.ToCString (), DACL_SECURITY_INFORMATION |
690 OWNER_SECURITY_INFORMATION
693 !_osd_wnt_sd_to_protection (
695 _get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE) == FLAG_DIRECTORY)
698 _osd_wnt_set_error ( myError, OSD_WFileNode );
702 FreeFileSecurity ( pSD );
706 } // end OSD_FileNode :: Protection
708 //=======================================================================
709 //function : SetProtection
711 //=======================================================================
713 void OSD_FileNode::SetProtection ( const OSD_Protection& Prot ) {
715 TCollection_AsciiString fName;
716 PSECURITY_DESCRIPTOR pSD;
718 myPath.SystemName ( fName );
720 TEST_RAISE( TEXT( "SetProtection" ) );
722 pSD = _osd_wnt_protection_to_sd (
724 _get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE) ==
726 (char *)fName.ToCString ()
729 if ( pSD == NULL || !SetFileSecurity (
730 fName.ToCString (), DACL_SECURITY_INFORMATION, pSD
734 _osd_wnt_set_error ( myError, OSD_WFileNode, fName.ToCString () );
740 } // end OSD_FileNode :: SetProtection
742 //=======================================================================
743 //function : AccessMoment
745 //=======================================================================
747 Quantity_Date OSD_FileNode::AccessMoment () {
749 Quantity_Date retVal;
750 SYSTEMTIME stAccessMoment;
751 SYSTEMTIME stAccessSystemMoment;
752 TCollection_AsciiString fName;
754 myPath.SystemName ( fName );
756 TEST_RAISE( TEXT( "AccessMoment" ) );
758 // if ( _get_file_time ( fName.ToCString (), &stAccessMoment, TRUE ) )
759 if ( _get_file_time ( fName.ToCString (), &stAccessSystemMoment, TRUE ) )
762 SYSTEMTIME * aSysTime = &stAccessMoment;
763 BOOL aFlag = SystemTimeToTzSpecificLocalTime (NULL ,
764 &stAccessSystemMoment ,
766 if (aFlag == 0) // AGV: test for success (e.g., unsupported on Win95/98)
767 aSysTime = &stAccessSystemMoment;
768 retVal.SetValues (aSysTime->wMonth, aSysTime->wDay,
769 aSysTime->wYear, aSysTime->wHour,
770 aSysTime->wMinute, aSysTime->wSecond,
771 aSysTime->wMilliseconds
776 _osd_wnt_set_error ( myError, OSD_WFileNode, fName.ToCString () );
780 } // end OSD_FileNode :: AccessMoment
782 //=======================================================================
783 //function : CreationMoment
785 //=======================================================================
787 Quantity_Date OSD_FileNode::CreationMoment () {
789 Quantity_Date retVal;
790 SYSTEMTIME stCreationMoment;
791 SYSTEMTIME stCreationSystemMoment;
792 TCollection_AsciiString fName;
794 myPath.SystemName ( fName );
796 TEST_RAISE( TEXT( "CreationMoment" ) );
798 // if ( _get_file_time ( fName.ToCString (), &stCreationMoment, FALSE ) )
799 if ( _get_file_time ( fName.ToCString (), &stCreationSystemMoment, TRUE ) )
802 SYSTEMTIME * aSysTime = &stCreationMoment;
803 BOOL aFlag = SystemTimeToTzSpecificLocalTime (NULL,
804 &stCreationSystemMoment ,
806 if (aFlag == 0) // AGV: test for success (e.g., unsupported on Win95/98)
807 aSysTime = &stCreationSystemMoment;
808 retVal.SetValues (aSysTime->wMonth, aSysTime->wDay,
809 aSysTime->wYear, aSysTime->wHour,
810 aSysTime->wMinute, aSysTime->wSecond,
811 aSysTime->wMilliseconds
816 _osd_wnt_set_error ( myError, OSD_WFileNode, fName.ToCString () );
820 } // end OSD_FileNode :: CreationMoment
822 //=======================================================================
825 //=======================================================================
827 Standard_Integer OSD_FileNode::UserId () {
829 PSID pSIDowner = NULL;
832 TCollection_AsciiString fName;
833 PSECURITY_DESCRIPTOR pSD;
835 myPath.SystemName ( fName );
837 TEST_RAISE( TEXT( "UserId" ) );
839 if ( ( pSD = GetFileSecurityEx (
841 OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION
844 GetSecurityDescriptorOwner ( pSD, &pSIDowner, &fDefaulted ) &&
848 retVal = CopySidEx ( pSIDowner );
852 _osd_wnt_set_error ( myError, OSD_WFileNode );
856 FreeFileSecurity ( pSD );
858 return ( Standard_Integer )retVal;
860 } // end OSD_FileNode :: UserId
862 //=======================================================================
865 //=======================================================================
867 Standard_Integer OSD_FileNode::GroupId () {
869 PGROUP_SID retVal = NULL;
870 TCollection_AsciiString fName;
871 PSECURITY_DESCRIPTOR pSD;
873 myPath.SystemName ( fName );
875 TEST_RAISE( TEXT( "GroupId" ) );
877 if ( ( pSD = GetFileSecurityEx (
879 OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION
884 retVal = AllocGroupSid ( pSD );
885 FreeFileSecurity ( pSD );
889 _osd_wnt_set_error ( myError, OSD_WFileNode );
891 return ( Standard_Integer )retVal;
893 } // end OSD_FileNode :: GroupId
895 //=======================================================================
898 //=======================================================================
900 Standard_Boolean OSD_FileNode::Failed () const {
902 return myError.Failed ();
904 } // end OSD_FileNode :: Failed
906 //=======================================================================
909 //=======================================================================
911 void OSD_FileNode::Reset () {
915 } // end OSD_FileNode :: Reset
917 //=======================================================================
920 //=======================================================================
922 void OSD_FileNode::Perror () {
926 } // end OSD_FileNode :: Perror
928 //=======================================================================
931 //=======================================================================
933 Standard_Integer OSD_FileNode::Error () const {
935 return myError.Error ();
937 } // end OSD_FileNode :: Error
939 void _osd_wnt_set_error ( OSD_Error& err, OSD_WhoAmI who, ... ) {
942 Standard_Character buffer[ 2048 ];
945 va_start ( arg_ptr, err );
947 errCode = GetLastError ();
949 if ( !FormatMessage (
950 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
951 0, errCode, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ),
952 buffer, 2048, &arg_ptr
956 sprintf ( buffer, "error code %d", (Standard_Integer)errCode );
957 SetLastError ( errCode );
961 err.SetValue ( errCode, who, buffer );
967 #if defined(__CYGWIN32__) || defined(__MINGW32__)
970 #define __leave return retVal
973 static BOOL __fastcall _get_file_time (
974 Standard_CString fName, LPSYSTEMTIME lpSysTime, BOOL fAccess
978 FILETIME ftCreationTime;
979 FILETIME ftLastWriteTime;
981 HANDLE hFile = INVALID_HANDLE_VALUE;
985 if ( ( hFile = CreateFile (
986 fName, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
988 ) == INVALID_HANDLE_VALUE
991 if ( !GetFileTime ( hFile, &ftCreationTime, NULL, &ftLastWriteTime ) ) __leave;
993 lpftPtr = fAccess ? &ftLastWriteTime : &ftCreationTime;
995 if ( !FileTimeToSystemTime ( lpftPtr, lpSysTime ) ) __leave;
1003 if ( hFile != INVALID_HANDLE_VALUE )
1005 CloseHandle ( hFile );
1010 leave: ; // added for VisualAge
1015 } // end _get_file_time
1017 #if defined(__CYGWIN32__) || defined(__MINGW32__)
1023 static void __fastcall _test_raise ( TCollection_AsciiString fName, Standard_CString str ) {
1025 Standard_Character buff[ 64 ];
1027 if ( fName.IsEmpty () ) {
1029 _tcscpy ( buff, TEXT( "OSD_FileNode :: " ) );
1030 _tcscat ( buff, str );
1031 _tcscat ( buff, TEXT( " (): wrong access" ) );
1033 Standard_ProgramError :: Raise ( buff );
1037 } // end _test_raise