Krusader freezes when renaming a file that is inside an archive
Open, Needs TriagePublic

Description

When renaming a file inside an archive, krarc freezes; you have to kill krusader to get krarc works again.

gengisdave added a comment.EditedAug 18 2016, 9:43 PM

The problem starts here: the job is started but it is never completed.

Removing the third parameter KIO::HideProgressInfo shows that the job never stops (in Plasma notifier); if you manually stop the job, krarc turns fine and nothing has happened.

If you kill and restart Krusader, you'll see an empty file in the archive with the destination filename (this not happens if you stop the rename job).

Debugging krarc, I found that the error is raised here

At a first analysis, the source QUrl must refer to a local file (you can copy a file inside the zip, but you can't from another zip).

EDIT 1 : renaming is impossible also in Krusader 2.4.0

Thanks, Davide, for your investigation! If I understand things right, we just need to implement the copy operation for non-local source files. Is it a good idea to use a temporary file/folder for that? What do You think?

gengisdave added a comment.EditedAug 20 2016, 10:54 PM

This explain very well the problem. We can't use kio_krarcProtocol::copy to rename an item inside an archive, and krArc doesn't have a rename method, so we must implement it.

In fact, the copy isn't designed to rename files (src.fileName() and dest.fileName() must be the same string).

Looking at the supported packers, I haven't found an option to rename a file without extracting it. The trick could be to extract the file, rename it, put in the archive and then delete the original one (obviously, only for the packers that have write support). It could look like:

void kio_krarcProtocol::rename(const QUrl & src, const QUrl & dest, JobFlags flags)
{
    tmp = <tmp_path> + src.fileName();
    // extract the file
    copy(src, tmp, flags);
    // rename it or some other way
    QFile file(tmp);
    file.rename(dest.fileName());
    // copy inside the archive
    get(<tmp_path> + dest.fileName());
    put(dest, -1, flags);
    // delete src
    del(src, true);
}

I can see from your recent post in T3419 that you are almost working on it. Sorry, I didn't answer for a longer time. I'm actually trying to pull this off right now with help of your advice above. But I was not yet successful. I'll keep trying but if you want dive in, that's definitely ok with me :-).

Atm, this task is almost a discussion, if you have already done some work, no problem. I'm focused on kio_iso T3490 (the solution to recognize path with symlinks, the other one is trivial).

I've found myself studying how does kio slave work in general to properly debug and understand the code. So it will probably take me some time before I can fix this. If it takes too long and You would be tempted to do it yourself, that's still OK with me. Due to lack of time this issue will take me a bit longer...sorry.