nwatalk: probe mars_nwe AFP entry ids from xattrs
All checks were successful
Source release / source-package (push) Successful in 48s
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:
11
TODO.md
11
TODO.md
@@ -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.
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user