Netatalk / netatalk

Netatalk is a Free and Open Source AFP fileserver. A *NIX or BSD system running Netatalk is capable of serving many Macintosh clients simultaneously as an AppleShare file server.
https://netatalk.io
GNU General Public License v2.0
335 stars 86 forks source link

Support for setting custom icons using `ad set` #1603

Open ssokolow opened 1 day ago

ssokolow commented 1 day ago

Is your feature request related to a problem? Please describe.

I maintain a hybrid Samba/Netatalk server for my vintage machines and it's very inconvenient and needlessly error-prone to have to temporarily remove read only = yes from the "FTP site full of freeware, shareware, and system updates... except it's Samba and AppleShare" and "My media library" shares every time I add new content just because I can't set the Mac OS icons from the Linux side.

Describe the solution you'd like

For general applicability, I'd like to see ad set extended to be able to set the actual custom icons on files and folders, rather than just the "I have one" flag, to complement its existing ability to set HFS creator and type codes.

Ideally, with support for loading to and saving from something easier to find an editor for on the Linux side, such as a stack of .png files or, for a more .ico-like editing experience, an OpenRaster document.

(OpenRaster is a "stack of PNGs in a Zip file" format that's supported by GIMP, Krita, MyPaint, and a bunch of other stuff. Here's a proof of concept I wrote a couple of days ago for using it to implement a "Use external editor" option for mask editing. ...though I will note that the .ora support is currently missing from the Ubuntu .deb for GIMP, so I had to switch to the Flatpak.)

Describe alternatives you've considered

Something like FinderPop's "Set File Type" menu, where no conversion is needed and you just give it a template file for it to copy the creator and type codes and/or custom icon from... as long as it still also supports copying icons to and from folders.

I just prefer the non-template approach because it's more consistent with the existing way ad set works and, if the non-template approach is implemented well, the template approach should just be a trivial shell script away, but the reverse isn't true.

(Plus, the non-template approach would let me script setting the Mac OS icons for .ico files to a preview of their contents like Graphic Converter does without risking altering the contents of the data fork.)

EDIT: Oh, and using ad to copy files from /srv/file_drop to /srv/retro errors out on my system (the former is a read-write volume, the latter is the read-only "FTP site, but AppleShare and Samba") so I'm not sure a template-based "Set File Type" would fare any better.

ssokolow commented 11 hours ago

For the record, I found a slightly less inconvenient workaround for adding icons to existing folders on the Linux side:

  1. Set the icon on an empty folder on Mac OS
  2. Copy the empty folder to /srv/file_drop via AppleShare
  3. Replace the existing folder using something like this untested shell-script-ifying of the manual steps I verified to work:
#!/bin/bash
# Usage: $0 /path/to/empty/folder /path/to/existing/folder

mv "$2" "$2".old  # Move existing folder out of the way
mv "$1" "$2"  # Move new folder, including set icon, into place
mv "$2".old/{*,.*} "$2"  # Move contents of old folder into new folder
rmdir "$2".old  # Remove iconless old folder

Still nowhere near ideal, but it doesn't require me to understand what that EA blob means or to keep setting and un-setting read only = yes or to figure out why I can't ad mv between different AppleShare volumes.

(Though I just remembered that I'll need a little more scripting to copy over the other Extended Attributes since I believe I've got Samba set to store the Windows file attributes there to make setting System for custom folder icons on Win9x more reliable.)

NJRoadfan commented 7 hours ago

Editing icons is outside the scope of the project.

An easier solution would be to setup the appropriate permissions for the share. ie: enable read only guest access and read/write access when logging in as a user. The "ad cp" command is respecting your share's read only flag and will not attempt to write to your share by design.

The EAs can be copied by using --preserve=xattr switch with cp. Netatalk's EA blob is in AppleDouble format and can be parsed and edited directly if needed. Its slightly more convenient to edit EAs in Python, but you can do it direct from the shell too if you dump it to a file with getfattr, edit, and then rewrite with setfattr.

ssokolow commented 6 hours ago

Editing icons is outside the scope of the project.

That's fair. I do tend to get a little carried away when my user-experience brain kicks in.

The minimal core of what I was asking for was more along the lines of "Could ad set be at least as featurful as the mac's native "Get Info" dialog?" which would just call for a way to copy the icon from one file or directory to another as an opaque blob.

I'm not sure if that would still count as "editing" them, but, from a user-experience standpoint, it certainly feels more in-scope.

An easier solution would be to setup the appropriate permissions for the share. ie: enable read only guest access and read/write access when logging in as a user.

Unfortunately, not really an option.

It's set blanket read-only for several reasons, including that I want to ensure these modifications can't be made remotely, regardless of what username or password is given. (To the point where, if I ever get around to locking down my systemd unit file permissions, I'll probably sandbox Netatalk off from being able to modify the shares marked as read only = yes.)

Plus, I really would prefer to assemble a solution for creating and setting icons analogous to how the Retro68 toolchain's LaunchAPPLServer lets you develop on classic Mac OS applications in your usual IDE/editor with your usual keyboard and mouse cursor acceleration profile and usual Linux keybindings and then launch built binaries remotely on the vintage mac, similar to how adb lets you remotely launch them on a connected Android device. (And likewise for whatever Apple calls the iOS equivalent.)

The "ad cp" command is respecting your share's read only flag and will not attempt to write to your share by design.

Is there any chance that a changed design could at least be opted into?

It seems very counter-intuitive to me that a CLI command which doesn't ask for a server to connect to would then apply the rules the server imposes on remote clients.

(i.e. ad feels like it's supposed to serve a role similar to what getfacl/setfacl is to chmod, but for the additional metadata that Netatalk hangs off files and directories. However, the permissions model it's enforcing feels more suited to something like smbclient which asks for a server to connect to and then manipulates things remotely.)

I'm also very confused about what is gained from doing it this way. If I'm permissioned to bypass ad and perform every action it can do by manipulating the files directly, and ad also operates locally rather than over a network connection, so I can't use it to alter metadata on a remote server, then what is meant to be achieved by forcing me to do things the less convenient way?

(Especially when, if I'm seeking out something like ad instead of looking up a Linux AFP client I can use to interact with some other machine as easily as 127.0.0.1, it's probably because I want to perform local administration.)

Netatalk's EA blob is in AppleDouble format and can be parsed and edited directly if needed. Its slightly more convenient to edit EAs in Python, but you can do it direct from the shell too if you dump it to a file with getfattr, edit, and then rewrite with setfattr.

Thanks. :)

That's a huge help. Last time I tried to figure out what format it was in, a lack of useful Google or DuckDuckGo results led me to trying to find the answer in Netatalk's source and I didn't have enough time to get very far.

Python's been one of my primary languages for 20+ years so, if I can find time to write a fix or workaround for the "--create doesn’t support external files (e.g. you can’t create a resource fork of PICTs from PNG files)." entry in rsrcdump's "Known limitations" section, that'd solve a lot.