Maintain file permissions when renaming
Temporary and autosave files do not neccessarily have the correct permissions set to replace existing project files. This updates the permissions to match the existing values where possible Fixes https://gitlab.com/kicad/code/kicad/-/issues/13574
This commit is contained in:
parent
122be418bb
commit
48ecd742eb
|
@ -63,6 +63,7 @@
|
||||||
#include <wx/stdpaths.h>
|
#include <wx/stdpaths.h>
|
||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
#include <kiplatform/app.h>
|
#include <kiplatform/app.h>
|
||||||
|
#include <kiplatform/io.h>
|
||||||
#include <kiplatform/ui.h>
|
#include <kiplatform/ui.h>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
@ -1295,6 +1296,9 @@ void EDA_BASE_FRAME::CheckForAutoSaveFile( const wxFileName& aFileName )
|
||||||
// the file name.
|
// the file name.
|
||||||
if( response == wxYES )
|
if( response == wxYES )
|
||||||
{
|
{
|
||||||
|
// Preserve the permissions of the current file
|
||||||
|
KIPLATFORM::IO::DuplicatePermissions( aFileName.GetFullPath(), autoSaveFileName.GetFullPath() );
|
||||||
|
|
||||||
if( !wxRenameFile( autoSaveFileName.GetFullPath(), aFileName.GetFullPath() ) )
|
if( !wxRenameFile( autoSaveFileName.GetFullPath(), aFileName.GetFullPath() ) )
|
||||||
{
|
{
|
||||||
wxMessageBox( _( "The auto save file could not be renamed to the board file name." ),
|
wxMessageBox( _( "The auto save file could not be renamed to the board file name." ),
|
||||||
|
|
|
@ -71,6 +71,8 @@
|
||||||
#include <widgets/wx_progress_reporters.h>
|
#include <widgets/wx_progress_reporters.h>
|
||||||
#include <widgets/wx_html_report_box.h>
|
#include <widgets/wx_html_report_box.h>
|
||||||
|
|
||||||
|
#include <kiplatform/io.h>
|
||||||
|
|
||||||
#if wxCHECK_VERSION( 3, 1, 7 )
|
#if wxCHECK_VERSION( 3, 1, 7 )
|
||||||
#include "widgets/filedlg_hook_save_project.h"
|
#include "widgets/filedlg_hook_save_project.h"
|
||||||
#else
|
#else
|
||||||
|
@ -741,6 +743,8 @@ bool SCH_EDIT_FRAME::saveSchematicFile( SCH_SHEET* aSheet, const wxString& aSave
|
||||||
|
|
||||||
if( success )
|
if( success )
|
||||||
{
|
{
|
||||||
|
// Preserve the permissions of the current file
|
||||||
|
KIPLATFORM::IO::DuplicatePermissions( schematicFileName.GetFullPath(), tempFile );
|
||||||
// Replace the original with the temporary file we just wrote
|
// Replace the original with the temporary file we just wrote
|
||||||
success = wxRenameFile( tempFile, schematicFileName.GetFullPath() );
|
success = wxRenameFile( tempFile, schematicFileName.GetFullPath() );
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <confirm.h>
|
#include <confirm.h>
|
||||||
#include <gestfich.h>
|
#include <gestfich.h>
|
||||||
#include <kiplatform/environment.h>
|
#include <kiplatform/environment.h>
|
||||||
|
#include <kiplatform/io.h>
|
||||||
#include <kiway.h>
|
#include <kiway.h>
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
#include <tools/kicad_manager_actions.h>
|
#include <tools/kicad_manager_actions.h>
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
FILE* KIPLATFORM::IO::SeqFOpen( const wxString& aPath, const wxString& aMode )
|
FILE* KIPLATFORM::IO::SeqFOpen( const wxString& aPath, const wxString& aMode )
|
||||||
{
|
{
|
||||||
|
@ -32,3 +34,26 @@ FILE* KIPLATFORM::IO::SeqFOpen( const wxString& aPath, const wxString& aMode )
|
||||||
|
|
||||||
return fp;
|
return fp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool KIPLATFORM::IO::DuplicatePermissions( const wxString &aSrc, const wxString &aDest )
|
||||||
|
{
|
||||||
|
struct stat sourceStat;
|
||||||
|
if( stat( aSrc.fn_str(), &sourceStat ) == 0 )
|
||||||
|
{
|
||||||
|
mode_t permissions = sourceStat.st_mode & ( S_IRWXU | S_IRWXG | S_IRWXO );
|
||||||
|
if( chmod( aDest.fn_str(), permissions ) == 0 )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Handle error
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Handle error
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -37,6 +37,13 @@ namespace IO
|
||||||
* to say linux and it's posix_fadvise
|
* to say linux and it's posix_fadvise
|
||||||
*/
|
*/
|
||||||
FILE* SeqFOpen( const wxString& aPath, const wxString& mode );
|
FILE* SeqFOpen( const wxString& aPath, const wxString& mode );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Duplicates the file security data from one file to another ensuring that they are
|
||||||
|
* the same between both. This assumes that the user has permission to set #aDest
|
||||||
|
* @return true if the process was successful
|
||||||
|
*/
|
||||||
|
bool DuplicatePermissions( const wxString& aSrc, const wxString& aDest );
|
||||||
} // namespace IO
|
} // namespace IO
|
||||||
} // namespace KIPLATFORM
|
} // namespace KIPLATFORM
|
||||||
|
|
||||||
|
|
|
@ -69,3 +69,41 @@ FILE* KIPLATFORM::IO::SeqFOpen( const wxString& aPath, const wxString& aMode )
|
||||||
return wxFopen( aPath, aMode );
|
return wxFopen( aPath, aMode );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool KIPLATFORM::IO::DuplicatePermissions( const wxString &aSrc, const wxString &aDest )
|
||||||
|
{
|
||||||
|
bool retval = false;
|
||||||
|
PSECURITY_DESCRIPTOR pSD = nullptr;
|
||||||
|
DWORD dwSize = 0;
|
||||||
|
|
||||||
|
// Retrieve the security descriptor from the source file
|
||||||
|
if( GetFileSecurity( sourceFilePath.wc_str(),
|
||||||
|
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
|
||||||
|
NULL, 0, &dwSize ) )
|
||||||
|
{
|
||||||
|
pSD = static_cast<PSECURITY_DESCRIPTOR>( new BYTE[dwSize] );
|
||||||
|
|
||||||
|
if( !pSD )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( !GetFileSecurity( sourceFilePath.wc_str(),
|
||||||
|
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION
|
||||||
|
| DACL_SECURITY_INFORMATION, pSD, dwSize, &dwSize ) )
|
||||||
|
{
|
||||||
|
delete[] pSD;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign the retrieved security descriptor to the destination file
|
||||||
|
if( !SetFileSecurity( destFilePath.wc_str(),
|
||||||
|
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION
|
||||||
|
| DACL_SECURITY_INFORMATION, pSD ) )
|
||||||
|
{
|
||||||
|
retval = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] pSD;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
#include <kiplatform/io.h>
|
#include <kiplatform/io.h>
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
#include <wx/crt.h>
|
#include <wx/crt.h>
|
||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
|
|
||||||
|
@ -26,3 +28,37 @@ FILE* KIPLATFORM::IO::SeqFOpen( const wxString& aPath, const wxString& aMode )
|
||||||
{
|
{
|
||||||
return wxFopen( aPath, aMode );
|
return wxFopen( aPath, aMode );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AssignPermissions(const wxString& sourceFilePath, const wxString& destFilePath)
|
||||||
|
{
|
||||||
|
NSString *sourcePath = [NSString stringWithUTF8String:sourceFilePath.utf8_str()];
|
||||||
|
NSString *destPath = [NSString stringWithUTF8String:destFilePath.utf8_str()];
|
||||||
|
|
||||||
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||||
|
|
||||||
|
NSError *error;
|
||||||
|
NSDictionary *sourceAttributes = [fileManager attributesOfItemAtPath:sourcePath error:&error];
|
||||||
|
|
||||||
|
if( !sourceAttributes )
|
||||||
|
{
|
||||||
|
NSLog(@"Error retrieving source file attributes: %@", error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSNumber *permissions = sourceAttributes[NSFilePosixPermissions];
|
||||||
|
|
||||||
|
if (permissions == nil)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([fileManager setAttributes:@{NSFilePosixPermissions: permissions} ofItemAtPath:destPath error:&error])
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSLog(@"Error assigning permissions: %@", error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,6 +32,8 @@
|
||||||
#include <widgets/wx_infobar.h>
|
#include <widgets/wx_infobar.h>
|
||||||
#include <wildcards_and_files_ext.h>
|
#include <wildcards_and_files_ext.h>
|
||||||
|
|
||||||
|
#include <kiplatform/io.h>
|
||||||
|
|
||||||
#include "pl_editor_frame.h"
|
#include "pl_editor_frame.h"
|
||||||
#include "pl_editor_id.h"
|
#include "pl_editor_id.h"
|
||||||
#include "properties_frame.h"
|
#include "properties_frame.h"
|
||||||
|
@ -307,6 +309,9 @@ bool PL_EDITOR_FRAME::SaveDrawingSheetFile( const wxString& aFullFileName )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Preserve the permissions of the current file
|
||||||
|
KIPLATFORM::IO::DuplicatePermissions( aFullFileName, tempFile );
|
||||||
|
|
||||||
if( !wxRenameFile( tempFile, aFullFileName ) )
|
if( !wxRenameFile( tempFile, aFullFileName ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
|
|
||||||
#include <footprint.h>
|
#include <footprint.h>
|
||||||
#include <pad.h>
|
#include <pad.h>
|
||||||
|
#include <kiplatform/io.h>
|
||||||
|
|
||||||
#include "step_pcb_model.h"
|
#include "step_pcb_model.h"
|
||||||
#include "streamwrapper.h"
|
#include "streamwrapper.h"
|
||||||
|
@ -831,6 +832,10 @@ bool STEP_PCB_MODEL::WriteSTEP( const wxString& aFileName )
|
||||||
|
|
||||||
if( success )
|
if( success )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Preserve the permissions of the current file
|
||||||
|
KIPLATFORM::IO::DuplicatePermissions( fn.GetFullPath(), tmpfname );
|
||||||
|
|
||||||
if( !wxRenameFile( tmpfname, fn.GetFullName(), true ) )
|
if( !wxRenameFile( tmpfname, fn.GetFullName(), true ) )
|
||||||
{
|
{
|
||||||
ReportMessage( wxString::Format( wxT( "Cannot rename temporary file '%s' to '%s'.\n" ),
|
ReportMessage( wxString::Format( wxT( "Cannot rename temporary file '%s' to '%s'.\n" ),
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <confirm.h>
|
#include <confirm.h>
|
||||||
#include <core/arraydim.h>
|
#include <core/arraydim.h>
|
||||||
#include <gestfich.h>
|
#include <gestfich.h>
|
||||||
|
@ -57,13 +59,14 @@
|
||||||
#include <plugins/cadstar/cadstar_pcb_archive_plugin.h>
|
#include <plugins/cadstar/cadstar_pcb_archive_plugin.h>
|
||||||
#include <plugins/kicad/pcb_plugin.h>
|
#include <plugins/kicad/pcb_plugin.h>
|
||||||
#include <dialogs/dialog_imported_layers.h>
|
#include <dialogs/dialog_imported_layers.h>
|
||||||
#include <string>
|
|
||||||
#include <tools/pcb_actions.h>
|
#include <tools/pcb_actions.h>
|
||||||
#include "footprint_info_impl.h"
|
#include "footprint_info_impl.h"
|
||||||
#include "board_commit.h"
|
#include "board_commit.h"
|
||||||
#include "zone_filler.h"
|
#include "zone_filler.h"
|
||||||
#include <wx_filename.h> // For ::ResolvePossibleSymlinks()
|
#include <wx_filename.h> // For ::ResolvePossibleSymlinks()
|
||||||
|
|
||||||
|
#include <kiplatform/io.h>
|
||||||
|
|
||||||
#include <wx/wupdlock.h>
|
#include <wx/wupdlock.h>
|
||||||
#include <wx/filedlg.h>
|
#include <wx/filedlg.h>
|
||||||
#include <wx/wfstream.h>
|
#include <wx/wfstream.h>
|
||||||
|
@ -1093,6 +1096,9 @@ bool PCB_EDIT_FRAME::SavePcbFile( const wxString& aFileName, bool addToHistory,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Preserve the permissions of the current file
|
||||||
|
KIPLATFORM::IO::DuplicatePermissions( pcbFileName.GetFullPath(), tempFile );
|
||||||
|
|
||||||
// If save succeeded, replace the original with what we just wrote
|
// If save succeeded, replace the original with what we just wrote
|
||||||
if( !wxRenameFile( tempFile, pcbFileName.GetFullPath() ) )
|
if( !wxRenameFile( tempFile, pcbFileName.GetFullPath() ) )
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#include <thread_pool.h>
|
#include <thread_pool.h>
|
||||||
#include <wildcards_and_files_ext.h>
|
#include <wildcards_and_files_ext.h>
|
||||||
|
|
||||||
|
#include <kiplatform/io.h>
|
||||||
|
|
||||||
#include <wx/textfile.h>
|
#include <wx/textfile.h>
|
||||||
#include <wx/txtstrm.h>
|
#include <wx/txtstrm.h>
|
||||||
#include <wx/wfstream.h>
|
#include <wx/wfstream.h>
|
||||||
|
@ -331,6 +333,9 @@ void FOOTPRINT_LIST_IMPL::WriteCacheToFile( const wxString& aFilePath )
|
||||||
txtStream.Flush();
|
txtStream.Flush();
|
||||||
outStream.Close();
|
outStream.Close();
|
||||||
|
|
||||||
|
// Preserve the permissions of the current file
|
||||||
|
KIPLATFORM::IO::DuplicatePermissions( aFilePath, tmpFileName.GetFullPath() );
|
||||||
|
|
||||||
if( !wxRenameFile( tmpFileName.GetFullPath(), aFilePath, true ) )
|
if( !wxRenameFile( tmpFileName.GetFullPath(), aFilePath, true ) )
|
||||||
{
|
{
|
||||||
// cleanup in case rename failed
|
// cleanup in case rename failed
|
||||||
|
|
|
@ -55,6 +55,8 @@
|
||||||
#include <zone.h>
|
#include <zone.h>
|
||||||
#include <zones.h>
|
#include <zones.h>
|
||||||
|
|
||||||
|
#include <kiplatform/io.h>
|
||||||
|
|
||||||
// For some reason wxWidgets is built with wxUSE_BASE64 unset so expose the wxWidgets
|
// For some reason wxWidgets is built with wxUSE_BASE64 unset so expose the wxWidgets
|
||||||
// base64 code. Needed for PCB_BITMAP
|
// base64 code. Needed for PCB_BITMAP
|
||||||
#define wxUSE_BASE64 1
|
#define wxUSE_BASE64 1
|
||||||
|
@ -129,6 +131,9 @@ void FP_CACHE::Save( FOOTPRINT* aFootprint )
|
||||||
// and it is fully inexplicable. See if this dodges the error.
|
// and it is fully inexplicable. See if this dodges the error.
|
||||||
wxMilliSleep( 250L );
|
wxMilliSleep( 250L );
|
||||||
|
|
||||||
|
// Preserve the permissions of the current file
|
||||||
|
KIPLATFORM::IO::DuplicatePermissions( fn.GetFullPath(), tempFileName );
|
||||||
|
|
||||||
if( !wxRenameFile( tempFileName, fn.GetFullPath() ) )
|
if( !wxRenameFile( tempFileName, fn.GetFullPath() ) )
|
||||||
{
|
{
|
||||||
wxString msg = wxString::Format( _( "Cannot rename temporary file '%s' to '%s'" ),
|
wxString msg = wxString::Format( _( "Cannot rename temporary file '%s' to '%s'" ),
|
||||||
|
|
Loading…
Reference in New Issue