nwatalk: probe mars_nwe AFP entry ids from xattrs
All checks were successful
Source release / source-package (push) Successful in 48s

Add the first mars_nwe-owned AFP metadata xattr reader before expanding the AFP write surface.  The new versioned org.mars-nwe.afp.entry-id payload gives the compatibility layer a stable, project-owned namespace for persistent AFP entry ids without reusing the unreleased user.mars_nwe.* test names or pretending that Netatalk-owned org.netatalk.* keys are ours to mutate.

The lookup order remains conservative: an existing mars_nwe entry-id xattr wins, then the optional Netatalk/libatalk AppleDouble/CNID helper is consulted, and the AFP handlers continue to fall back to their stat-derived temporary id when no persistent metadata exists.  No Set File Information, CNID allocation, Finder Info write, or resource-fork write path is introduced here.

This keeps the WebSDK/NWAFP read-only endpoint semantics intact while preparing the metadata storage boundary needed by later AFP Set File Information and CNID work.  ENABLE_NETATALK_LIBATALK=OFF still rejects AFP calls at the handler guard, and the xattr reader has an XATTR_SUPPORT-disabled stub so non-xattr builds keep compiling.

Tests:

- git diff --check

- cmake --build build-xattr-off --target nwconn

- cmake -S . -B build-afp-on -DENABLE_NETATALK_LIBATALK=ON -DCMAKE_PREFIX_PATH=/mnt/data/afp_build_prefix

- cmake --build build-afp-on --target nwconn

TODO:

- Add a deliberate write-safe AFP metadata writer/allocator before enabling AFP 2.0 Set File Information.

- Decide whether future mars_nwe AFP metadata stays split across org.mars-nwe.afp.* keys or moves into a compact org.mars-nwe.afp.metadata record.
This commit is contained in:
ChatGPT
2026-05-30 09:09:07 +00:00
committed by Mario Fetka
parent a586e52b25
commit ca610c1100
3 changed files with 81 additions and 17 deletions

11
TODO.md
View File

@@ -271,9 +271,14 @@ Follow-up:
data/resource fork and Finder Info semantics.
- Replace the temporary stat-derived AFP entry-id fallback with a persistent
CNID/directory-id mapping once the libatalk/CNID backend is integrated.
- Put future mars_nwe-owned AFP metadata under `org.mars-nwe.afp.*` (or a
compact `org.mars-nwe.afp.metadata` record) and keep Netatalk-owned metadata
under Netatalk's own `org.netatalk.*` keys.
- mars_nwe-owned AFP entry ids are probed first from the versioned
`org.mars-nwe.afp.entry-id` xattr before consulting Netatalk/libatalk
AppleDouble/CNID metadata and, finally, the stat-derived fallback. No AFP
metadata write path exists yet; Set File Information and CNID allocation
still need a deliberate write-safe design.
- Put additional future mars_nwe-owned AFP metadata under `org.mars-nwe.afp.*`
(or a compact `org.mars-nwe.afp.metadata` record) and keep Netatalk-owned
metadata under Netatalk's own `org.netatalk.*` keys.
- Extend the Linux AFP smoke tests once additional AFP subfunctions are
implemented, especially Finder Info updates, fork open/read/write paths,
resource-fork handling, and broader directory-scan edge cases.

View File

@@ -6,12 +6,58 @@
#include <string.h>
#if XATTR_SUPPORT
#include <sys/types.h>
#include <sys/xattr.h>
#endif
#if NETATALK_SUPPORT
#include <errno.h>
#include <sys/stat.h>
#include <atalk/adouble.h>
#endif
#define MARS_NWE_AFP_ENTRY_ID_XATTR "org.mars-nwe.afp.entry-id"
#define MARS_NWE_AFP_ENTRY_ID_VERSION 1
typedef struct {
uint8 version;
uint8 reserved[3];
uint8 entry_id[4];
} MARS_NWE_AFP_ENTRY_ID_XATTR_DATA;
#if XATTR_SUPPORT
static int nwatalk_get_mars_entry_id_xattr(const char *path, uint32 *entry_id)
{
MARS_NWE_AFP_ENTRY_ID_XATTR_DATA d;
ssize_t len;
uint32 id;
if (!entry_id) return(-0x9c);
*entry_id = 0;
if (!path || !*path) return(-0x9c);
memset(&d, 0, sizeof(d));
len = getxattr(path, MARS_NWE_AFP_ENTRY_ID_XATTR, &d, sizeof(d));
if (len != sizeof(d) || d.version != MARS_NWE_AFP_ENTRY_ID_VERSION)
return(-0x9c);
id = GET_BE32(d.entry_id);
id &= 0x7fffffffU;
if (!id) return(-0x9c);
*entry_id = id;
return(0);
}
#else
static int nwatalk_get_mars_entry_id_xattr(const char *path, uint32 *entry_id)
{
(void)path;
if (entry_id) *entry_id = 0;
return(-0xbf);
}
#endif
int nwatalk_backend_available(void)
{
#if NETATALK_SUPPORT
@@ -104,29 +150,35 @@ int nwatalk_get_resource_fork_size(const char *path, uint32 *resource_size)
int nwatalk_get_entry_id(const char *path, uint32 *entry_id)
{
#if NETATALK_SUPPORT
struct adouble ad;
struct stat stbuff;
uint32_t id;
int result;
if (!entry_id) return(-0x9c);
*entry_id = 0;
if (!path || !*path) return(-0x9c);
if (stat(path, &stbuff)) return(-0x9c);
result = nwatalk_get_mars_entry_id_xattr(path, entry_id);
if (!result && *entry_id)
return(0);
result = nwatalk_open_adouble(path, &ad);
if (result < 0) return(result);
#if NETATALK_SUPPORT
{
struct adouble ad;
struct stat stbuff;
uint32_t id;
id = ad_getid(&ad, stbuff.st_dev, stbuff.st_ino, 0, NULL);
if (id) *entry_id = (uint32)id;
if (stat(path, &stbuff)) return(-0x9c);
ad_close(&ad, 0);
return(id ? 0 : -0x9c);
result = nwatalk_open_adouble(path, &ad);
if (result < 0) return(result);
id = ad_getid(&ad, stbuff.st_dev, stbuff.st_ino, 0, NULL);
if (id) *entry_id = (uint32)id;
ad_close(&ad, 0);
return(id ? 0 : -0x9c);
}
#else
(void)path;
(void)entry_id;
(void)result;
return(-0xbf); /* invalid namespace / backend unavailable */
#endif
}

View File

@@ -7,6 +7,13 @@ The tests use the ncpfs/libncp client library. They are not built by default
because they require the host ncpfs development headers/library and a running
NetWare-compatible server.
The AFP endpoints are intentionally conservative. When persistent AFP entry
ids become available, mars_nwe-owned ids are read from the versioned
`org.mars-nwe.afp.entry-id` xattr before falling back to Netatalk/libatalk
AppleDouble/CNID metadata and then the temporary stat-derived fallback. The
current smoke tests do not write AFP metadata; Set File Information and CNID
allocation remain separate write-safety work.
Build with:
```sh