Files
mars-nwe/src/nwxattr.c
OpenAI 995a1e6cd7
All checks were successful
Source release / source-package (push) Successful in 49s
nwconn: add AFP FinderInfo set smoke path
Implement a deliberately narrow write-safe slice of the WebSDK/NWAFP Set File Information semantics for the NCP 0x2222/35/16 AFP 2.0 Set File Information call.

The only accepted request bitmap is the FinderInfo bit (0x0020). The handler uses the same path-backed raw VOL:-style compatibility subset as the existing AFP get, scan, open-fork, and temporary-directory-handle smoke endpoints, resolves the effective NetWare volume from the path prefix, rejects entry-id-only lookup until persistent CNID/base-ID mapping exists, and rejects directory or non-FinderInfo writes rather than pretending to implement DOS attribute, timestamp, delete-protect, resource-fork, or broader Mac namespace write semantics.

Store the 32-byte FinderInfo block in mars_nwe-owned metadata under the source-level xattr name org.mars-nwe.afp.finder-info and teach the existing AFP file-info response builder to read that value before falling back to Netatalk/libatalk AppleDouble FinderInfo. This makes the write immediately verifiable through AFP 2.0 Get File Information without changing data-fork or resource-fork contents.

Add a small local xattr abstraction for mars_nwe-private metadata names. Netatalk exposes names such as org.netatalk.Metadata at the libatalk layer, but prefixes them with user. on Linux inside its EA wrapper. Mirror that behavior for mars_nwe so source code and documentation use org.mars-nwe.* consistently while Linux stores user.org.mars-nwe.* where the kernel requires a namespace prefix. Convert the existing archive/fileinfo xattr calls to the same wrapper so the previous org.mars-nwe.* namespace rename remains functional on Linux.

Add tests/linux/afp_set_file_info_smoke, which sends AFP 0x10 with a FinderInfo bitmap, then verifies the result through AFP 0x0f Get File Information. Document the smoke command, expected output, server-log shape, and the remaining unsupported Set File Information write semantics.

Tests: git diff --check; gcc -Iinclude -I/mnt/data/stubs -fsyntax-only tests/linux/afp_set_file_info_smoke.c; cmake --build build-off --target nwconn with ENABLE_NETATALK_LIBATALK=OFF; cmake --build build-on --target nwconn with ENABLE_NETATALK_LIBATALK=ON against Netatalk-4.4.3 headers and local link stubs.
2026-05-30 11:29:33 +02:00

86 lines
1.9 KiB
C

/* nwxattr.c - mars_nwe extended attribute namespace helpers */
#include "config.h"
#include "nwxattr.h"
#include <errno.h>
#include <string.h>
#if XATTR_SUPPORT
#include <sys/types.h>
#include <sys/xattr.h>
#endif
#if XATTR_SUPPORT
static const char *mars_nwe_xattr_name(const char *name,
char *buffer, size_t buffer_len)
{
if (!name || !*name) return(name);
if (!strncmp(name, "user.", 5) ||
!strncmp(name, "trusted.", 8) ||
!strncmp(name, "security.", 9) ||
!strncmp(name, "system.", 7))
return(name);
#if defined(__APPLE__) || defined(SOLARIS)
(void)buffer;
(void)buffer_len;
return(name);
#else
if (buffer_len < 6) return(name);
strncpy(buffer, "user.", buffer_len);
buffer[buffer_len - 1] = '\0';
strncat(buffer, name, buffer_len - strlen(buffer) - 1);
return(buffer);
#endif
}
#endif
ssize_t mars_nwe_getxattr(const char *path, const char *name,
void *value, size_t size)
{
#if XATTR_SUPPORT
char xname[256 + 5];
return(getxattr(path, mars_nwe_xattr_name(name, xname, sizeof(xname)),
value, size));
#else
(void)path;
(void)name;
(void)value;
(void)size;
errno = ENOTSUP;
return(-1);
#endif
}
int mars_nwe_setxattr(const char *path, const char *name,
const void *value, size_t size, int flags)
{
#if XATTR_SUPPORT
char xname[256 + 5];
return(setxattr(path, mars_nwe_xattr_name(name, xname, sizeof(xname)),
value, size, flags));
#else
(void)path;
(void)name;
(void)value;
(void)size;
(void)flags;
errno = ENOTSUP;
return(-1);
#endif
}
int mars_nwe_removexattr(const char *path, const char *name)
{
#if XATTR_SUPPORT
char xname[256 + 5];
return(removexattr(path, mars_nwe_xattr_name(name, xname, sizeof(xname))));
#else
(void)path;
(void)name;
errno = ENOTSUP;
return(-1);
#endif
}