Syncthing-Android 0.2.0 released

You’ll still need a flag to activate the behavior (unless we can somehow reliable and portably detect filesystems without permission support), so the behavior doesn’t necessarily need to be the exact same.

One thing that we could do is a sort of compatibility check per repository when starting up. Create a file with an odd modification time and specific permission set - say 0736 or something - and then stat the file and see what we get. Modification time changed? We have a filesystem without full second resolution. Permission bits mangled? The filesystem doesn’t support permissions, etc.

Of course this is all a shot in the dark if a single repo consists of multiple filesystems, etc, but there’s only so much we can do to handle all the weird stuff out there.

With “flag” I meant the one in the protocol definition (instead of always setting permissions to 666/644).

Yeah, I don’t think I maybe fully got how that was going to work. If you think that’s a better solution, please expand on it. What makes me skeptic to a protocol flag is that this is a very local thing; there might be 10 nodes sharing a repository, one of which can’t fully represent timestamps and one of which doesn’t understand permissions. We don’t want to force that behavior on the other nodes or have to make some kind of cluster wide decision on this. The “handicapped” nodes should sort it out for themselves somehow.

My plan was to set the flag only when sending from a “no permissions” node.

So when an Android node (with syncPermissions=false) sends data, the flag is set, and other nodes ignore the actual permission bits. When a normal linux node sends data, the flag is unset and permissions are sent as usual (if an Android node receives that data, it just ignores the permission bits).

So the flag is only set when sending from a node that has syncPermissions=false.

The Android side would still need to send some set of permission bits, or other nodes have no idea what to use (consider that a file is created Android-side).

I figured we’d use the default permissions on file creation (whatever those are, maybe just by not setting anything?).

But you still want to distinguish read/write from read only, no? Perhaps we should not have only an “ignore permissions” flag, but a permissions bitmask. A “permission challenged” node would send the permission bits it sees, and a bitmask indicating which bits are actually relevant - i.e. something like 0666 / 0600 to say “stat returned 0666 for the file; I only understand read and write bits for the user, so disregard the rest”. For incoming bitmasks, the permission challenged node would only compare bits set in the bitmask.

Then again, that still leaves some things to be desired. The following scenario is crap, for example:

  • File created on Linux, mode 0660. Synced to Android. Everyone happy.
  • File set to read only on Android. Change sent to the other cluster nodes, mode is 0444.
  • What do they do?
    • Today, they would accept the mode as 0444 which lets everyone read the file so is less restrictive than before. That’s probably not intended.
    • With the permission bitmask, we would set the mode to 0460 (only change the bits in the bitmask), which is obviously wrong.
    • With permissions ignored, the file remains as 0660 (not read only).

Tricky…

Oh, and s/Android/Windows/ on the above as well so this is not a ridiculously unusual scenario even though perhaps few people change file modes on Android.

So, what’s the bottom line on this? I’m especially unsure where the bitmask would come from. Entered by the user? Auto-detected?

Anyway, I could code it one way or another, but I don’t totally get it yet.

Googling around, I get the impression BTsync doesn’t even try and just lets the user configure the permissions that should be set on all files that are written (this could be wrong, I haven’t tested). Dropbox completely ignores the issue and sets all files to 0644. I think the simplest solution is the winner here. So:

A new flag in the protocol, bit 17 “P” that indicates “ignore permission bits”, and set all permission bits to zero on transmission. When receiving indexes, ignore permission bits on any files with the P flag set and create files with the default permission bits (umask). Enable the flag in question by setting an option on the repo config, possibly aided by auto detection.

This was pretty much your initial suggest, so we are in agreement?

Yeah right. So I’ll start implementing it, with the repository attribute syncPermissions (but no auto detection yet).

I already started hacking up the basics, so hold off a few seconds. :slight_smile:

Yes I saw it, you’re way too fast for me :smiley:

Just tell me if there’s anything left to do for me.

What’s about a setting on every node or every repro. I would like to have every file to 0660

There, try the latest master. There’s a new option as discussed that I think does approximately what it’s supposed to…

That should be what happens now, if you check the new “ignore permissions” flag everywhere and make sure your system umask is 006…

Yes it works. It’s definitely not backwards compatible though (v0.8.9 sets permissions to 000 on change). Maybe you should set the permission bits to sensible defaults so this does not completely break old versions?

Btw I noticed that empty files aren’t synced, even though they are counted towards the file total. Might be worth fixing.

I’ll change the Android app, so that the flag is set before every start on each repo, and add a notice in the startup dialog not to disable it.

Right, the backwards compatibility should be considered.

Empty files should be synced just fine; there are even tests for this.

The Android app no longer accepts upper case in the repository name, counter to the fix in 0.8.13.

This is in the .12 version of the app. Creating the repo in the GUI with a lower case name and then manually editing it in config.xml partially works: the app will start but you can’t then assign any nodes to sync with (and you can’t really do that manually unless you are a complete masochist).

The repository ID is correct (uppercase) in the expanded view, but as soon as you click to edit it, the field still contains the default name… :frowning:

This was actually fixed in syncthing v0.8.13, but I just noticed that I fucked up the update to that version, so syncthing-android still runs v0.8.12. Will be fixed in the next version.

Thanks for the fix.

Is it just me, or does every update require a complete reinstall? After updating, I try and open Syncthing and then get the dreaded “Unfortunately, Syncthing has stopped.”

The only way, that I have found, around this is to reinstall, copy the new ID to all the other nodes and then rinse and repeat…

I’m using CM 10.0 if that makes any difference.