0 votes

Hello,

We meet some problems to save the skipper files in a shared directory.

Our architecture :
- Skipper 3.2.8.1347 with 2 users license
- Skipper runs on a Ubuntu 16.04 session.
- The shared files are hosted on a Linux Debian local server, with CIFS protocol.

Skipper can open its file (Entity.skipper for example, rights 666).
When we try to save the file (even without change), Skipper create a backup file Entity.skipper.bak (rights 644 ; why 644?) and tries to rewrite the Entity.skipper file with rights 700!
Then an error occurs:
Exception diagnostic info:
Throw location unknown (consider using BOOSTTHROWEXCEPTION)
Dynamic exception type: boost::exceptiondetail::cloneimpl<boost::exceptiondetail::errorinfo_injector >
std::exception::what: failed opening file: Access denied

What we are doing wrong?

Many thanks!

asked Jan 17 in Solved by adarvaux (140 points)
recategorized Mar 17 by ludek.vodicka

1 Answer

0 votes

Hi, thanks for your question. Unfortunately, this seems to be some problem in your OS. Because we don't specify any permissions during file creation. We're using standard boost file system library for creating & copying the files.

Mentioned .bak file is to protect your original file in case that save is interrupted by any way. Because of that we first create .bak file and when save is successful we remove .bak file.

For copying file from .skipper to .bak we're usign following routine (so as you can see no permissions are configured/changed):

boost::filesystem::copy_file(pathFromFile, pathToFile);

and for creating new files (.bak) we're using the following routine

//maped file params
boost::iostreams::basic_mapped_file_params<boostpath> mfp;
mfp.path = fileName.GetAsBoostPath();
mfp.flags = boost::iostreams::mapped_file::readwrite;
mfp.offset = 0;
mfp.new_file_size = lBufferSize;

//open and write to file
boost::iostreams::mapped_file_sink mf(mfp);
memory_trait::CopyMemoryBuffer(pBuffer, mf.data(), lBufferSize);

//close file
mf.close();

I believe that all files are created with permissions based on the user who run the application. Until now we don't receive any similar bug report, so I believe it has to be by some configuration on your side.

answered Jan 17 by ludek.vodicka Skipper developer (125,850 points)

It works! With this version (3.2.9.1351) the rights of Skipper files (xxx.skipper) are kept and the rights of the annotations files (xxx.php) as well.
Well done!
I'll now use this Skipper version with a real project and I hope all will be fine.
Many thanks, Ludek

Perfect. It should work smoothly because these are only two changes made in the code.

Damned! the problem remains with the xxx.skipper.bak file :-(
It comes :

Can't copy file [/media/ResidentService/ResidentService.skipper] to [/media/ResidentService/ResidentService.skipper.bak]. Error: boost::filesystem::copy_file: Access denied: "/media/ResidentService/ResidentService.skipper", "/media/ResidentService/ResidentService.skipper.bak"

or, if I create manually the xxx.skipper.bak file before (always with rights 666):

Can't delete file [/media/ResidentService/ResidentService.skipper.bak]. Error: boost::filesystem::remove: Access denied: "/media/ResidentService/ResidentService.skipper.bak"

Moreover, I wonder why sometimes Skipper tries to generate a bak file, sometimes not. Obviously, I haven't understood something :-D
Can we deactivate the bak file generation? In our case, we do not need this function...

Sooorry : it was my fault (I had not given the correct rights to my project folder).

Anyway, I continue to not understand how works the bak files generation. Does it exist some documentation about this subject?

I changed backup logic several times during testing the permission issue. In your current version is backup performed by followign steps:

//backup old files if exists
XPROGRESS_CHANNEL(Atomix::ProgressChannels::status, _TR("Backuping old project files"));
BOOST_FOREACH(TpairFileNameContent &pairFileContent, lstStoredFiles)
{
    if ( axFileHelper::CheckIfFileExists(pairFileContent.first) == true )
        axFileHelper::CopyFile(pairFileContent.first, pairFileContent.first + ".bak");
}

//creating new storage files
XPROGRESS_CHANNEL(Atomix::ProgressChannels::status, _TR("Saving to project files"));
BOOST_FOREACH(TpairFileNameContent &pairFileContent, lstStoredFiles)
{
    XString &strContent = pairFileContent.second;
    XPROGRESS_CHANNEL_FMT(Atomix::ProgressChannels::status, _TR("Saving XML file %ts"), pairFileContent.first.GetAsPCXSTR());
    axDirectoryHelper::CreateDirectoryPath(pairFileContent.first.GetPath());
    axFileHelper::SaveStringToFileUTF8(pairFileContent.first, strContent);
}

//erasing old files
XPROGRESS_CHANNEL(Atomix::ProgressChannels::status, _TR("Removing backup files"));
BOOST_FOREACH(TpairFileNameContent &pairFileContent, lstStoredFiles)
{
    if ( axFileHelper::CheckIfFileExists(pairFileContent.first + ".bak") == true )
        axFileHelper::DeleteFile(pairFileContent.first + ".bak");
}
  • So, as first step all existing skipper files are copied to new location. This cause the permission change for .bak, but enable us to keep original permission on .skipper file. (originally there was "MoveFile").

  • Then content of skipper files is stored inside the existing files (originally, there was creating of new files).

  • And as last step backup files were removed. This is the same like in previous versions.