Commit Graph

283 Commits

Author SHA1 Message Date
OpenAI
2f71b73fca tests: extend AFP smoke suite for metadata attributes
All checks were successful
Source release / source-package (push) Successful in 46s
The AFP Set File Information smoke coverage now includes the additional metadata-only file attribute bits implemented after the original FinderInfo and Invisible checks.  Extend the collectable Linux smoke-suite helper so a single report covers FinderInfo, Invisible set/clear, System set/clear, and Backup set/clear before dumping the mars_nwe AFP xattrs.

This keeps the helper aligned with the WebSDK/NWAFP attribute bitmap semantics exercised by afp_set_file_info_smoke: the Attributes request bitmap remains 0x0001, while the request attribute word uses SETCLR when setting System or Backup and the plain bit when clearing.  The suite clears each tested bit again so repeated runs normally leave org.mars-nwe.afp.attributes in the clean versioned zero state.

Document the runtime probes reported from SYS:PUBLIC/pmdflts.ini, including the AFP-visible attrs values and the server diagnostics that show the encoded SETCLR forms.  Also update TODO so the current smoke status states that the report helper now follows the supported FinderInfo plus Invisible/System/Backup metadata subset.

Tests:\n- bash -n tests/linux/afp_smoke_suite.sh\n- git diff --check\n\nTODO:\n- Keep rejecting the rest of AFP Set File Information until timestamp, enforcement, DOS/NetWare mapping, resource-fork, and entry-id-only write semantics are designed.
2026-05-30 13:03:59 +02:00
ChatGPT
cfd036e54c nwconn: persist additional AFP metadata attributes
All checks were successful
Source release / source-package (push) Successful in 49s
Extend the conservative AFP 2.0 Set File Information smoke path to accept the metadata-only System and Backup file attribute bits alongside the already-supported Finder Invisible bit.

The WebSDK/NWAFP Set File Information request uses the file Attributes bitmap to pass a set/clear attribute word. Netatalk stores several AFP file attributes in AppleDouble metadata while computing open-fork state dynamically and leaving enforcement-sensitive bits to the file/fork paths. Mirror only the low-risk mars_nwe subset here: persist Invisible, System, and Backup in the private org.mars-nwe.afp.attributes xattr, and keep NoWrite, NoRename, NoDelete, NoCopy, data-fork-open, resource-fork-open, timestamps, resource forks, and Entry-ID-only write semantics rejected until they have deliberate enforcement and backend design.

The xattr payload remains versioned and unchanged. Reads now expose the three supported metadata bits through Get/Scan File Information, and writes preserve the existing set/clear semantics over the supported mask.

Update the Linux Set File Information smoke helper with --system/--clear-system and --backup/--clear-backup options, while keeping the smoke-suite default unchanged. Document the expected Linux xattr forms 0x01000004 and 0x01000040 for those optional probes.

Tests: git diff --check; gcc -Iinclude -I/mnt/data/stubs -fsyntax-only tests/linux/afp_set_file_info_smoke.c.
2026-05-30 12:55:25 +02:00
Mario Fetka
c57af8c7dc tests: record AFP smoke suite success
All checks were successful
Source release / source-package (push) Successful in 52s
Document the green Linux AFP smoke-suite report after the FinderInfo Set File Information payload-alignment fix.

The report covers the WebSDK/NWAFP smoke path for Entry ID by path, Entry ID from a live NetWare handle, Get File Information, Scan File Information, Alloc Temporary Directory Handle, Open File Fork, FinderInfo Set File Information, and Finder Invisible set/clear.  Record the suite-level failures=0 result for SYS:PUBLIC/pmdflts.ini so the current AFP compatibility baseline is captured in a single place.

Also record the Linux xattr evidence that matters for the metadata write paths: the FinderInfo value now starts with TEXTMARS without the previous leading padding byte, the attributes xattr reflects Invisible clear as 0x01000000 after the set/clear round-trip, and the cached mars_nwe AFP entry-id xattr stores 0x33f9a1ed in the versioned payload format.

Tests: external runtime report from tests/linux/afp_smoke_suite.sh against MARS/SUPERVISOR with SYS:PUBLIC/pmdflts.ini showed failures=0.
2026-05-30 12:47:52 +02:00
OpenAI
6fcd5c294e tests: fix AFP FinderInfo smoke payload alignment
All checks were successful
Source release / source-package (push) Successful in 47s
The AFP Set File Information smoke helper builds the NCP 0x23/0x10 payload without the leading AFP subfunction byte that nwconn sees in its server-side request buffer.  The helper already aligned the FinderInfo data offset in server coordinates and then translated it back to the client payload buffer by subtracting that byte.

A second alignment check after the translation shifted FinderInfo-only requests with even-length paths by one byte.  The server then persisted the padding byte as the first FinderInfo byte, which produced xattrs such as 0x00544558544d415253... and verification output with got_creator=TMAR instead of TEXT/MARS.

Keep the WebSDK/header bitmap semantics unchanged: bitmap 0x0020 still carries exactly a 32-byte FinderInfo block after the path and padding, and bitmap 0x0001 still carries the two-byte AFP attribute word.  Only the Linux smoke helper's payload construction is corrected so it matches the server's subfunction-prefixed AFP request layout.

Tests:

- git diff --check

- gcc -Iinclude -I/mnt/data/stubs -fsyntax-only tests/linux/afp_set_file_info_smoke.c

TODO:

- Re-run afp_smoke_suite.sh and confirm FinderInfo xattr starts with 0x544558544d415253 and the suite reports failures=0.
2026-05-30 12:43:39 +02:00
Mario Fetka
3fa06b4c15 tests: add AFP smoke-suite report helper
All checks were successful
Source release / source-package (push) Successful in 50s
Add an optional Linux-side AFP smoke-suite shell helper that runs the
currently verified AFP NCP 0x2222/35 probes as a single collectable report.
The helper is intended for the same ncpfs/libncp smoke workflow as the
individual C helpers, but it groups the read-only probes, the narrow Set File
Information metadata writes, Linux xattr verification, and a filtered AFP
server-log excerpt so runtime results can be pasted back into follow-up
test-status patches.

Keep the command lines safe to share by masking the password in the printed
report while still passing the real value to the helpers. Parameterize the
server, user, password, NetWare path, Unix path, mars_nwe log file,
FinderInfo type/creator, and output file so the script can be used against
SYS:PUBLIC as well as other exported volumes.

Copy the script into the CMake binary tests/linux directory when
MARS_NWE_BUILD_LINUX_TESTS is enabled, preserving executable permissions. The
script does not add new AFP semantics; it only automates the existing helpers
and documents the Linux xattr names used by the mars_nwe AFP metadata wrapper.

Tests:
- bash -n tests/linux/afp_smoke_suite.sh
- ./tests/linux/afp_smoke_suite.sh --help
- git diff --check
2026-05-30 12:37:05 +02:00
OpenAI
c51fde95fe nwconn: persist AFP invisible file attributes
All checks were successful
Source release / source-package (push) Successful in 47s
Extend the conservative NCP 0x2222/35/16 AFP 2.0 Set File Information smoke path beyond FinderInfo-only writes by accepting the file Attributes bitmap for one deliberately narrow bit: Finder Invisible.

WebSDK and Netatalk FPSetFileParams semantics carry file attributes as bitmap bit 0, with ATTRBIT_SETCLR selecting set-vs-clear behavior. Mirror that model only for ATTRBIT_INVISIBLE and reject all other AFP attribute bits so DOS/NetWare mode bits, timestamp writes, resource forks, and broader file protection semantics are not implied accidentally.

Persist the mars_nwe-owned AFP attribute word in org.mars-nwe.afp.attributes via the local xattr abstraction. On Linux this maps to user.org.mars-nwe.afp.attributes, matching the org.mars-nwe.* source-level namespace while remaining portable on Linux xattr backends. Get File Information and Scan File Information now merge that stored Invisible bit into the existing 120-byte AFP file-info record.

Update the Linux Set File Information smoke helper with --invisible, --clear-invisible, --attributes-only, and --finder-info-only so FinderInfo and the narrow AFP attribute path can be tested independently or together.

Tests: git diff --check

Tests: gcc -Iinclude -I/mnt/data/stubs -fsyntax-only tests/linux/afp_set_file_info_smoke.c

TODO: keep all other AFP Set File Information bits rejected until their write-safe mapping to NetWare/DOS attributes, timestamps, CNID, and resource-fork metadata is designed.
2026-05-30 12:23:03 +02:00
OpenAI
97bce6edf5 tests: document AFP entry-id xattr scan smoke results
All checks were successful
Source release / source-package (push) Successful in 48s
Document the Linux smoke results for the mars_nwe-owned AFP Entry ID xattr cache after the first runtime probes wrote versioned org.mars-nwe.afp.entry-id metadata.

The documented xattr payloads use the source-level org.mars-nwe.afp.entry-id name, which mars_nwe maps to Linux user.org.mars-nwe.afp.entry-id storage.  The examples record the version byte, reserved bytes, and big-endian AFP Entry ID values observed for pmdflts.ini and pmgate.sys.

Also clarify the scan continuation semantics exposed by the new smoke run.  AFP Scan File Information currently follows server directory iteration order: last_seen skips past the previously returned object, but the next returned Entry ID is not required to be numerically greater than the continuation token.  This avoids documenting an accidental Entry-ID-sort guarantee while the implementation still lacks a full CNID-backed Mac namespace scan layer.

Tests:

- ./afp_entry_id_smoke ... SYS:PUBLIC/pmdflts.ini

- ./afp_scan_info_smoke ... SYS:PUBLIC

- ./afp_scan_info_smoke ... --last-seen 0x260437f6 SYS:PUBLIC

- ./afp_scan_info_smoke ... --last-seen 0x6686342b SYS:PUBLIC

- getfattr -n user.org.mars-nwe.afp.entry-id -e hex .../pmdflts.ini

- getfattr -n user.org.mars-nwe.afp.entry-id -e hex .../pmgate.sys
2026-05-30 12:11:40 +02:00
OpenAI
4637f3ee57 nwatalk: cache AFP fallback entry ids in xattrs
All checks were successful
Source release / source-package (push) Successful in 48s
The AFP smoke endpoints can now read mars_nwe-owned entry ids from the versioned org.mars-nwe.afp.entry-id xattr, but a newly discovered file still had to fall back to the temporary stat-derived id on every request until a real CNID allocator exists.

Preserve the existing WebSDK/NWAFP response semantics while making that fallback sticky: when Get Entry ID, Get File Information, or Scan File Information has no mars_nwe xattr and no Netatalk/libatalk AppleDouble/CNID id, derive the existing compatibility id and cache it through nwatalk_set_entry_id().  The first request still logs fallback so diagnostics remain honest about the id origin; subsequent requests should read the xattr directly and avoid re-entering the stat fallback path.

Keep the write narrowly scoped to mars_nwe's private AFP metadata namespace.  The payload is versioned, big-endian, and stored through the nwxattr helper, so Linux persists it as user.org.mars-nwe.afp.entry-id while source-level code continues to use the Netatalk-style org.mars-nwe.afp.entry-id name.  This does not implement CNID allocation, parent-id lookup, entry-id-only resolution, FinderInfo mutation beyond the existing smoke path, or resource-fork semantics.

Tests:

- git diff --check

- cmake --build build-xattr-off --target nwconn with ENABLE_NETATALK_LIBATALK=OFF

- cmake --build build-xattr-on --target nwconn with ENABLE_NETATALK_LIBATALK=ON against Netatalk 4.4.3 headers plus local link stubs
2026-05-30 11:56:43 +02:00
OpenAI
8c99eaa68b tests: record AFP FinderInfo set smoke result
All checks were successful
Source release / source-package (push) Successful in 47s
Document the runtime smoke coverage for NCP 0x2222/35/16, AFP 2.0 Set File Information, after the first write-safe FinderInfo subset was exercised through ncpfs/libncp.

The helper writes the WebSDK/header-level FinderInfo bitmap only, persists the 32-byte FinderInfo block in the mars_nwe AFP metadata xattr, and verifies the result with a follow-up AFP 2.0 Get File Information request.  Record the known-good SYS:PUBLIC/pmdflts.ini invocation result with Finder type TEXT and creator MARS.

Also clarify the diagnostic semantics of the follow-up Get File Information line: the reported fallback marker describes the entry-id source, which is still stat-derived when no persistent mars_nwe AFP entry-id xattr or Netatalk/CNID metadata exists.  It is not a FinderInfo write failure.

Tests:

- ./afp_set_file_info_smoke -S MARS -U SUPERVISOR -P ... --type TEXT --creator MARS SYS:PUBLIC/pmdflts.ini

TODO:

- Keep all other AFP 2.0 Set File Information bitmap bits rejected until their write semantics are explicitly designed.
2026-05-30 11:48:34 +02:00
OpenAI
b8016f99a3 nwarchive: scope private xattrs under NetWare namespace
All checks were successful
Source release / source-package (push) Successful in 48s
Move the mars_nwe NetWare-core archive/fileinfo xattr names from the flat org.mars-nwe namespace into an explicit org.mars-nwe.netware subnamespace.

The earlier xattr namespace cleanup intentionally removed the unreleased user.mars_nwe names and introduced Netatalk-style org.mars-nwe source-level keys.  Keeping archive and fileinfo at org.mars-nwe.archive and org.mars-nwe.fileinfo would make those NetWare server metadata records peers of AFP metadata instead of identifying their ownership.  The archive date/time/archiver and file create/creator/modifier records are NetWare-core file metadata, so place them under org.mars-nwe.netware.* while leaving AFP metadata under org.mars-nwe.afp.*.

No legacy fallback is added because the old names only existed in local test systems and have not been released.  The existing nwxattr wrapper still maps source-level org.mars-nwe.<domain>.* names to user.org.mars-nwe.<domain>.* on Linux, mirroring Netatalk's org.netatalk.* EA abstraction.

Tests: git diff --check

TODO: keep future nwbind/nwserv/AFP metadata in explicit org.mars-nwe.<domain>.* subnamespaces instead of adding new flat org.mars-nwe.* keys.
2026-05-30 11:41:43 +02:00
OpenAI
995a1e6cd7 nwconn: add AFP FinderInfo set smoke path
All checks were successful
Source release / source-package (push) Successful in 49s
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
ChatGPT
ca610c1100 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.
2026-05-30 11:11:15 +02:00
ChatGPT
a586e52b25 nwarchive: move private xattrs to org namespace
All checks were successful
Source release / source-package (push) Successful in 49s
Rename the unreleased mars_nwe private archive and file-info extended-attribute keys from the Linux user.mars_nwe.* spelling to the Netatalk-style org.mars-nwe.* namespace.

This keeps the mars_nwe metadata namespace aligned with the AFP/libatalk backend direction, where Netatalk owns org.netatalk.* keys and mars_nwe-owned metadata should live under org.mars-nwe.* instead of looking like ordinary user application attributes.

No legacy read fallback is added because the user.mars_nwe.* names have only existed in local test builds and have not shipped in a release. New writes therefore use only org.mars-nwe.archive and org.mars-nwe.fileinfo, avoiding migration complexity before AFP metadata persistence is introduced.

Document the namespace decision in TODO.md so future AFP xattr work can build on org.mars-nwe.afp.* or a compact org.mars-nwe.afp.metadata record rather than adding new user.mars_nwe.* keys.

Tests: cmake --build build-xattr-off --target nwserv; cmake --build build-xattr-off --target all reaches the existing missing gdbm.h dependency while nwconn has already been built in this tree.
2026-05-30 11:04:03 +02:00
Mario Fetka
3f3753e2b5 tests: record AFP scan file information smoke results
All checks were successful
Source release / source-package (push) Successful in 50s
Record the verified Linux smoke-test output for NCP 0x2222/35 subfunctions 0x11 and 0x0a, AFP Scan File Information and AFP 2.0 Scan File Information.

The WebSDK/header-level request layout for both scan calls carries the Mac base directory id, last-seen entry id, desired response count, search bitmap, request bitmap, and path modifier.  The current mars_nwe implementation intentionally routes both variants through the same conservative path-backed directory scan and returns a single AFP file-information record per request.  Documenting the matching 0x11 and 0x0a first-record output makes that compatibility choice explicit.

The recorded continuation case also documents the current last_seen pagination contract: callers feed the returned next_last_seen AFP Entry ID back into the next request to advance through SYS:PUBLIC.  The sample entries remain stat-derived fallback Entry IDs with parent_id kept at zero until persistent CNID/AppleDouble/libatalk-backed directory identity is available.

Tests:

- ./afp_scan_info_smoke -S MARS -U SUPERVISOR -P ... SYS:PUBLIC

- ./afp_scan_info_smoke --afp10 -S MARS -U SUPERVISOR -P ... SYS:PUBLIC

- ./afp_scan_info_smoke -S MARS -U SUPERVISOR -P ... --last-seen 0x23c8787d SYS:PUBLIC

TODO:

- Add multi-response scan replies once the record packing and client-side parsing are widened beyond the current one-record smoke path.

- Replace stat-derived fallback Entry IDs with persistent CNID/AppleDouble/libatalk-backed IDs.
2026-05-30 10:46:50 +02:00
Mario Fetka
8e739a1ac2 nwconn: route AFP scan file information
All checks were successful
Source release / source-package (push) Successful in 49s
Add the older WebSDK/NWAFP AFP Scan File Information subfunction 0x0a to the AFP dispatcher and route it through the existing conservative directory-scan implementation used by AFP 2.0 Scan File Information 0x11.

The Micro Focus NCP documentation describes both scan variants as read-only directory/file information scans with a Mac base Entry ID, Mac last-seen ID, DesiredResponseCount, SearchBitMap, RequestBitMap, and path modifier.  The mars_nwe compatibility subset still requires a raw path-backed VOL:-style request because persistent CNID/base-ID lookup is not available yet, but accepting 0x0a lets older AFP callers probe the same read-only semantics instead of receiving Invalid Namespace for an otherwise implemented scan shape.

Teach the scan parser to accept the documented DesiredResponseCount word while keeping compatibility with the earlier compact smoke-test layout that omitted it.  For now DesiredResponseCount is logged and constrained by the smoke helper, while the server still returns one conservative file-info record plus the next-last-seen entry id per request.  This avoids pretending to implement full multi-response AFP directory scans before CNID-backed ordering, response-count batching, and AppleDouble metadata are available.

Extend afp_scan_info_smoke with --afp10/--afp20 selection and a documented --desired-count argument.  The helper now sends the WebSDK-style request layout by default, uses 0x11 unless --afp10 is requested, and keeps the existing next_last_seen output used for iterative Linux smoke tests.

Tests:

- git diff --check

- gcc -fsyntax-only tests/linux/afp_scan_info_smoke.c with local ncpfs header stubs

- 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

TODO:

- Implement persistent CNID/base-ID lookup so entry-id-only scans can work without a raw path.

- Replace the one-record smoke response with true DesiredResponseCount batching once stable CNID ordering and full AFP scan filtering are available.

- Fill richer AppleDouble/Finder/ProDOS/resource-fork metadata when the libatalk backend grows write-safe metadata support.
2026-05-30 10:39:02 +02:00
OpenAI
00060e0e93 nwconn: resolve AFP smoke path volumes
All checks were successful
Source release / source-package (push) Successful in 47s
Resolve the effective NetWare volume for path-backed AFP compatibility requests from the raw VOL: path prefix before opening data forks or allocating temporary directory handles.

The WebSDK/nwafp.h request layouts for AFP 0x08 Open File Fork and AFP 0x0b Alloc Temporary Directory Handle both carry a volume byte plus base AFP Entry ID.  The current mars_nwe smoke subset deliberately keeps Entry-ID-relative lookup disabled, but it accepts raw NetWare-style paths such as SYS:PUBLIC and HOME:LOGIN.  In that path-backed mode, treating dir_handle 0 as volume 0 in diagnostics is too narrow: build_path() already extracts the real volume from the VOL: prefix, and the lower NetWare open/dir-handle helpers use that same resolver internally.

Add a small AFP path-volume resolver wrapper around conn_get_kpl_unxname() and use it in the 0x08 and 0x0b handlers before delegating to nw_creat_open_file() or nw_alloc_dir_handle().  Successful diagnostics now report the resolved effective volume and keep the incoming request volume separately as request_vol, which preserves the header-level request shape without implying that non-SYS paths are opened on volume 0.

This does not add CNID/base-ID lookup, resource-fork handling, or write semantics.  Entry-ID-only requests remain Invalid Path until persistent AFP identity mapping is implemented.  The optional Netatalk/libatalk backend guard remains unchanged; ENABLE_NETATALK_LIBATALK=OFF still rejects these AFP calls with Invalid Namespace before any path-backed work is attempted.

Tests:

- git diff --check

- cmake --build build-off --target nwconn with ENABLE_NETATALK_LIBATALK=OFF

- cmake --build build-on --target nwconn with ENABLE_NETATALK_LIBATALK=ON requested; local tree reports backend disabled because libatalk headers/library are not installed

TODO:

- Runtime-smoke a non-SYS volume such as HOME: to confirm the diagnostic shows the resolved non-zero volume id.

- Replace path-backed smoke lookup with persistent CNID/base-ID lookup when the AFP metadata backend grows that support.
2026-05-30 10:19:18 +02:00
Mario Fetka
a98865dd78 tests: record AFP open file fork smoke results
Document the verified Linux smoke coverage for NCP 0x2222/35/08, AFP Open File Fork.

The implemented endpoint intentionally follows the same WebSDK/header-level subset as the other early AFP handlers: a path-backed request with volume/base Entry ID zero, data fork selection, and read access only.  The server returns the normal six-byte NetWare file handle shape plus the current data-fork length, and the smoke helper closes that handle in the same connection.

Record the known-good SUPERVISOR smoke results for SYS:PUBLIC/pmdflts.ini and SYS:PUBLIC/ohlogscr.bat together with their matching server log lines.  This makes the current semantics explicit: fork 0 is the data fork, access 0x01 is read-only, the handle value is connection-local, and fork_len is derived from the backing file contents.

Keep the TODO boundary visible for the parts that are not implemented yet: resource fork opens, write access, Entry-ID-only lookup, AppleDouble resource-fork data, and persistent CNID/base-ID lookup semantics.

Tests:

- Runtime smoke: ./afp_open_file_fork_smoke ... SYS:PUBLIC/pmdflts.ini

- Runtime smoke: ./afp_open_file_fork_smoke ... SYS:PUBLIC/ohlogscr.bat

- git diff --check
2026-05-30 10:10:52 +02:00
Mario Fetka
db9283a410 nwconn: implement AFP open file fork smoke path
All checks were successful
Source release / source-package (push) Successful in 46s
Implement the WebSDK/nwafp.h NCP 0x2222/35 AFP subfunction 0x08, Open File Fork, for the same conservative path-backed subset that the current AFP smoke endpoints use.

The request is decoded as volume number, AFP Entry ID, fork selector, access mode, path length, and AFP path.  Until persistent CNID/base-ID lookup exists, empty path / Entry-ID-only opens continue to fail with Invalid Path rather than pretending that the temporary stat-derived AFP Entry IDs are a durable namespace.  The handler also keeps resource forks and write access negative for now, because those require AppleDouble/resource-fork and write-safe Finder metadata semantics that are not implemented yet.

For the supported data-fork read-only case, delegate to the existing NetWare open-file path via nw_creat_open_file().  The reply returns the normal six-byte NetWare file handle shape used by the AFP handle APIs followed by the current data-fork length.  That lets follow-up smoke tests verify handle interoperability with AFP Get Entry ID From NetWare Handle and with the ordinary NetWare close path while keeping write/resource semantics conservative.

Add afp_open_file_fork_smoke so Linux ncpfs/libncp tests can exercise the endpoint through the same requester path as the other AFP probes.  The helper closes the returned handle in the same connection and documents the expected data-fork-only coverage in tests/linux/README.md and TODO.md.

Tests: git diff --check

Tests: cmake --build build-off --target nwconn with ENABLE_NETATALK_LIBATALK=OFF

Tests: cmake --build build-on --target nwconn with ENABLE_NETATALK_LIBATALK=ON requested; local environment lacks libatalk headers/library so CMake reports the metadata backend disabled, but the target still builds and the new handler has no direct libatalk symbol references

Tests: gcc -fsyntax-only tests/linux/afp_open_file_fork_smoke.c with local ncpfs header stubs

TODO: add persistent CNID/base-ID lookup, AppleDouble/resource-fork open support, and write-safe AFP fork semantics before accepting resource-fork or write-mode opens.
2026-05-30 10:04:26 +02:00
OpenAI
f6bda83f67 tests: record AFP temporary directory handle smoke results
All checks were successful
Source release / source-package (push) Successful in 47s
Record the runtime Linux smoke coverage for the WebSDK/NWAFP NCP 0x2222/35/11 AFP Alloc Temporary Directory Handle request.

The implementation already returned the AFP reply as a temporary NetWare directory handle plus the one-byte AFP access-rights field. The real server diagnostic, however, logs the wider internal NetWare effective-rights mask from nw_alloc_dir_handle(), which can report 0x1ff for a privileged directory while the client-visible AFP field prints as 0xff. Document that distinction so the README matches the tested server log instead of implying a logging or protocol mismatch.

Also widen the diagnostic printf field width to 0x%03x to make the 9-bit NetWare rights mask intentional in future logs. This is only a diagnostic formatting change; the wire reply remains the AFP byte-sized rights field used by the smoke helper.

Tests:

- Runtime smoke reported green for SYS:, SYS:PUBLIC, SYS:SYSTEM, and SYS:BURST

- git diff --check

TODO:

- Entry-ID-only temporary handle allocation still waits for persistent CNID/base-ID lookup.
2026-05-30 09:50:48 +02:00
Mario Fetka
162ff2b10f nwconn: implement AFP temporary directory handles
All checks were successful
Source release / source-package (push) Successful in 49s
Implement the WebSDK/nwafp.h NCP 0x2222/35 AFP subfunction 0x0b, Alloc Temporary Directory Handle, for the same conservative path-backed subset used by the current AFP Entry ID and File Information probes.\n\nThe documented request carries an AFP volume number, a base AFP Entry ID, and an optional AFP-style path.  mars_nwe still has no persistent CNID/base-ID lookup, so this patch deliberately accepts only requests with a path component and rejects entry-id-only allocation as Invalid Path.  For the supported smoke-test path, raw SYS:-style paths are resolved through the existing NetWare path machinery and the final handle is allocated with nw_alloc_dir_handle() as a temporary, task-scoped NetWare directory handle.\n\nThe implementation keeps the AFP namespace gate intact: without the optional Netatalk/libatalk backend, the endpoint continues to return Invalid Namespace rather than pretending that the Mac namespace exists.  With the backend enabled, successful replies contain the allocated temporary directory handle and the effective-rights mask returned by the existing directory-handle table.  Diagnostics include the AFP volume/base Entry ID input, path, returned handle, and rights so smoke-test output can be matched to server logs.\n\nAdd a Linux ncpfs/libncp smoke helper for the new endpoint.  The helper sends the AFP 0x0b request through NWRequestSimple(), prints the returned handle and rights mask, and immediately deallocates the handle in the same connection via the normal NetWare Deallocate Directory Handle call.  The README documents that these handles are connection/task-local and must not be copied into later tests or reused from server logs.\n\nTests:\n- git diff --check\n- gcc -fsyntax-only tests/linux/afp_temp_dir_handle_smoke.c with temporary local ncpfs header stubs\n\nNot run:\n- Full CMake build in this container: missing gdbm/ncpfs development headers/libraries.\n\nTODO:\n- Replace the path-backed subset with persistent CNID/base-ID lookup once the AFP metadata backend grows durable directory identity support.\n- Verify live Linux smoke cases against SYS:, SYS:PUBLIC, SYS:SYSTEM, and SYS:BURST on a mars_nwe host with ENABLE_NETATALK_LIBATALK=ON.
2026-05-30 09:27:51 +02:00
Mario Fetka
776c7e7510 tests: document AFP entry-id-from-handle smoke coverage
All checks were successful
Source release / source-package (push) Successful in 47s
Document the Linux smoke-test coverage for NCP 0x23 AFP subfunction 0x06, Get Entry ID From NetWare Handle.

The WebSDK documents the request as NCP 0x2222/35/06, with the SDK headers exposing the same operation through AFPGetEntryIDFromNetWareHandle() and NWAFPGetEntryIDFromNetWareHandle(). Unlike the path and name probes, this request is centered on a 6-byte NetWare file handle that is valid only in the current client connection.

Record the known-good libncp smoke invocations for SYS:PUBLIC files. The test opens each file in the same connection, passes the returned NetWare handle to the AFP request, and verifies the conservative reply shape: volume 0, a 32-bit AFP Entry ID, and data-fork indicator fork=0.

Also document the current implementation boundary. The returned Entry IDs are still stat-derived fallback values, server diagnostics mark them with fallback, parent Entry ID derivation remains conservative, and persistent CNID/AppleDouble/libatalk-backed identity plus AFP resource-fork handle semantics remain TODO work.

Tests:

- Documentation-only change; no binary rebuild required.

- Previously verified: ./afp_entry_id_smoke --from-handle -S MARS -U SUPERVISOR -P ... SYS:PUBLIC/pmdflts.ini

- Previously verified: ./afp_entry_id_smoke --from-handle -S MARS -U SUPERVISOR -P ... SYS:PUBLIC/ohlogscr.bat
2026-05-30 09:20:16 +02:00
Mario Fetka
a10f256b77 nwconn: implement AFP entry id from NetWare handle
All checks were successful
Source release / source-package (push) Successful in 49s
Wire NCP 0x23/0x06 AFP Get Entry ID From NetWare Handle to the existing AFP entry-id backend.

The WebSDK documents NCP 0x2222/35/06 as taking a 6-byte NetWare file handle and returning the volume number, a 32-bit AFP Entry ID, and a fork indicator. The SDK headers expose the same operation as AFPGetEntryIDFromNetWareHandle() and NWAFPGetEntryIDFromNetWareHandle().

Use the connection-local mars_nwe file handle table to map the supplied NetWare file handle back to its Unix path, require the optional libatalk backend as for the other AFP calls, and then return a libatalk Entry ID when available or the existing stat-derived fallback ID otherwise. Report the data fork for now because mars_nwe does not yet expose AFP resource-fork open semantics.

Extend the Linux AFP entry-id smoke test with --from-handle. The test opens the requested file through libncp in the same connection, sends the returned 6-byte NetWare file handle to the AFP call, and closes the file afterwards.

This implements the read-only data-fork handle-to-entry-id path; persistent CNID mapping and resource-fork handle semantics remain future work.
2026-05-30 09:08:25 +02:00
Mario Fetka
8cd0cad6fb tests: document AFP get-entry-id-from-name smoke coverage
All checks were successful
Source release / source-package (push) Successful in 49s
Document the Linux smoke coverage for NCP 0x23/0x04 AFP Get Entry ID From Name after the path-backed implementation was verified.

The same afp_entry_id_smoke tool now exercises both the older path-name probe and the name-based entry-id lookup. Record the --from-name examples for SYS:, SYS:PUBLIC, SYS:SYSTEM, and SYS:BURST, and note that the current implementation still returns stat-derived fallback Entry IDs until persistent CNID/AppleDouble mapping is available.

Update TODO.md so the implemented AFP status matches the tested endpoints while keeping the remaining base-entry-id-relative lookup and persistent Mac namespace work tracked as follow-up.
2026-05-30 08:59:47 +02:00
Mario Fetka
36615e3e66 tests: fix AFP entry-id smoke option diagnostics
All checks were successful
Source release / source-package (push) Successful in 47s
Fix two malformed fprintf() string literals introduced while adding the AFP Get Entry ID From Name smoke-test options.

The previous patch accidentally emitted literal newlines inside the diagnostic strings for invalid --volume and --entry-id arguments, which broke compilation of afp_entry_id_smoke.c.

This changes only Linux test diagnostics; AFP protocol behavior is unchanged.
2026-05-30 08:54:05 +02:00
Mario Fetka
3f2493ef25 nwconn: implement AFP Get Entry ID From Name
All checks were successful
Source release / source-package (push) Successful in 45s
Wire NCP 0x23/0x04 AFP Get Entry ID From Name to the same conservative path-backed Entry ID lookup used by the existing AFP path-name probe.

The WebSDK documents NCP 0x2222/35/04 as taking a volume number, an AFP base Entry ID, and an AFP path string that modifies that base, and returning the AFP Entry ID for the given path. The SDK headers expose the same call as NWAFPGetEntryIDFromName().

MARS-NWE does not yet maintain persistent CNID/base-ID lookup state, so support the verified SYS:-style path-backed subset first: require the optional libatalk backend, resolve the supplied path through the existing mars_nwe path machinery, and return the stored libatalk Entry ID when available or the existing stat-derived fallback Entry ID otherwise. Entry-ID-only lookup remains invalid path until persistent CNID/AppleDouble mapping is implemented.

Extend the Linux AFP Entry ID smoke test with --from-name so the new endpoint can be exercised without an AppleTalk client while keeping the existing 0x0c test path unchanged.

This adds the documented read-only Entry ID query path only; it does not add persistent AFP base-ID lookup or broader Mac namespace semantics.
2026-05-30 08:42:17 +02:00
Mario Fetka
2134f83ac4 tests: document AFP scan file information smoke coverage
All checks were successful
Source release / source-package (push) Successful in 47s
Document the Linux AFP 2.0 Scan File Information smoke coverage after the endpoint was verified against SYS:PUBLIC.

The scan test exercises the WebSDK-documented NCP 0x23/0x11 request by walking a directory one entry at a time and feeding the returned next_last_seen AFP Entry ID into the next request. Record the verified multi-entry SYS:PUBLIC sequence and explain that the current Entry IDs are still stat-derived fallback values until persistent CNID/AppleDouble mapping is implemented.

Update the Linux test README with the afp_scan_info_smoke build target and examples, and move Scan File Information out of the generic unimplemented AFP follow-up list while keeping broader scan edge cases and full Mac namespace work tracked.

This is documentation-only and does not change AFP protocol behavior.
2026-05-30 08:37:30 +02:00
Mario Fetka
800c7a6f26 nwconn: implement AFP scan file information
All checks were successful
Source release / source-package (push) Successful in 52s
Wire NCP 0x23/0x11 AFP 2.0 Scan File Information to a conservative read-only directory scan.

The WebSDK documents NWAFPScanFileInformation as taking a volume number, AFP base entry id, last-seen AFP id, search mask, request mask, path string, and file-info buffer. The call scans a directory relative to the AFP base and returns AFP file information for the next matching entry, updating the last-seen id for the caller's next iteration.

Reuse the existing AFP file information formatter and libatalk/stat-derived entry-id path. For now, support path-backed scans only: resolve the supplied SYS:-style path through the mars_nwe path machinery, enumerate one child directory entry after the supplied last-seen id, and return a last-seen id plus an AFP file-info record. Entry-id-only scans, persistent CNID lookup, and full AFP search-mask semantics remain future work.

Add a Linux afp_scan_info_smoke helper using ncpfs/libncp so the new endpoint can be exercised without an AppleTalk client.

This implements the documented read-only scan path needed for directory browsing smoke tests, while keeping write-side AFP and persistent Mac namespace semantics unchanged.
2026-05-30 08:26:35 +02:00
Mario Fetka
43dc118ea3 tests: document AFP 2.0 file information smoke coverage
All checks were successful
Source release / source-package (push) Successful in 48s
Document the verified AFP 2.0 Get File Information smoke-test coverage after the endpoint was exercised against the same standard SYS volume paths as the older AFP file-information call.

The Linux afp_file_info_smoke test now covers both NCP 0x23/0x05 and NCP 0x23/0x0f. Record that --afp20 was verified against SYS:, SYS:PUBLIC, SYS:SYSTEM, and SYS:BURST using the current path-backed read-only reply.

Keep the remaining AFP limitations explicit: the reply still uses stat/libatalk-derived fields, marks temporary Entry IDs with the fallback diagnostic, and leaves persistent CNID/AppleDouble IDs, Parent ID mapping, and fuller Mac namespace metadata as future work.

This is documentation-only and does not change AFP protocol behavior.
2026-05-30 08:20:05 +02:00
Mario Fetka
8e885bb16d nwconn: implement AFP 2.0 Get File Information
All checks were successful
Source release / source-package (push) Successful in 46s
Route NCP 0x23/0x0f AFP 2.0 Get File Information through the existing read-only AFP file-information helper.

The WebSDK and nwafp.h list both AFP Get File Information and AFP 2.0 Get File Information as path/file-information queries that return the AFP file-information record used by Mac namespace clients. The already implemented 0x05 path handles SYS:-style path requests and fills the safe read-only fields from Unix stat data plus the optional libatalk Finder Info and resource-fork helpers.

Use the same conservative path-backed reply for 0x0f for now. This gives Linux smoke-test coverage for the AFP 2.0 subfunction without adding entry-id-only lookup, persistent CNID mapping, write-side metadata updates, or fuller resource-fork semantics.

Extend afp_file_info_smoke with --afp20 so the same SYS:, SYS:PUBLIC, SYS:SYSTEM, and SYS:BURST cases can exercise the AFP 2.0 subfunction. Update the Linux test README and TODO tracking to record that AFP 2.0 file information is covered by the same temporary fallback model.

This implements only the read-only path-based subset; richer AFP 2.0 behavior remains future Mac-namespace work.
2026-05-30 08:05:46 +02:00
Mario Fetka
b3d06fbf3f tests: document AFP file information smoke coverage
All checks were successful
Source release / source-package (push) Successful in 47s
Document the Linux smoke-test coverage for the newly implemented AFP Get File Information endpoint.\n\nThe WebSDK-documented NCP 0x2222/35/05 path now has a Linux libncp smoke test alongside the existing AFP Entry ID probe. Record the verified SYS:, SYS:PUBLIC, SYS:SYSTEM, and SYS:BURST cases and describe the read-only reply fields currently populated from Unix stat data and the optional libatalk helper wrappers.\n\nAlso update the AFP Entry ID smoke-test documentation to match the current default raw-path mode, where SYS:-style paths are sent with directory handle 0 and handle allocation is kept behind --alloc-handle for separate debugging.\n\nKeep the remaining AFP/Mac namespace work in TODO.md, including persistent CNID/AppleDouble entry IDs, Parent ID mapping, Finder Info/resource-fork semantics, AFP 2.0 file information, and Scan File Information coverage.\n\nThis is documentation-only and does not change AFP protocol behavior.
2026-05-30 07:55:53 +02:00
Mario Fetka
8190673f27 tests: do not duplicate AFP file-info subfunction
All checks were successful
Source release / source-package (push) Successful in 49s
Do not include the AFP Get File Information subfunction byte in the NWRequestSimple payload when the request is already sent through NCPC_SFN().

libncp's subfunction request helper supplies the NCP 0x23 AFP subfunction on the wire. The smoke test also placed 0x05 as the first byte of its local payload, so mars_nwe received a duplicated subfunction byte. The server then decoded the low byte of the request mask as the path length, producing a boundary-check failure with path_len=255 before the path could be resolved.

Build the smoke-test payload as the data following the subfunction byte: Volume Number, AFP Entry ID, Request Bit Map, Path String Length, and Path String. This matches the server-side decoder, which sees the subfunction byte at afp_req[0].

This changes only the Linux smoke test; server AFP protocol behavior is unchanged.
2026-05-30 04:16:26 +02:00
Mario Fetka
03a5d69dc4 nwconn: implement AFP Get File Information
All checks were successful
Source release / source-package (push) Successful in 48s
Wire NCP 0x23/0x05 AFP Get File Information to a conservative read-only reply
for SYS:-style paths.

The WebSDK documents NCP 0x2222/35/05 as taking a Volume Number, AFP Entry ID,
request bit map, and AFP path modifier string, and returning an AFP file
information record with entry id, parent id, attributes, data and resource fork
lengths, offspring count, NetWare dates, Finder Info, long and short names,
owner id, access privileges, and ProDOS information. The SDK headers expose the
same call as AFPGetFileInformation() and NWAFPGetFileInformation(), with the
wire reply matching RECPKT_AFPFILEINFO.

Resolve the supplied path through the existing mars_nwe path machinery, require
the optional Netatalk/libatalk backend as for the entry-id probe, and fill the
fields that can be derived safely from Unix stat data and the existing libatalk
helpers. Finder Info and resource fork length are read through nwatalk when
present; entry ids fall back to the existing stat-derived AFP id until
persistent CNID/AppleDouble ids are implemented. Parent id and ProDOS-specific
data remain zero for now.

Add a Linux afp_file_info_smoke test using ncpfs/libncp so the new call can be
exercised without an AppleTalk client. The test sends raw SYS:-style paths with
directory handle 0, matching the verified AFP Entry ID smoke-test path.

This implements only the read-only AFP file information query for path-based
requests; entry-id-only lookup, persistent CNID mapping, and write-side AFP
semantics remain future work.
2026-05-30 03:59:50 +02:00
Mario Fetka
b365c90904 tests: default AFP smoke test to raw paths
Default the Linux AFP Entry ID smoke test to sending the supplied path directly
with directory handle 0.

The verified smoke cases use SYS:-style paths against mars_nwe, and those
requests reach NCP 0x23/0x0c and return Entry IDs. The intermediate automatic
temporary directory-handle allocation path is not required for that endpoint
coverage and can fail before the AFP request is sent, which makes the smoke
test diagnose the wrong subsystem.

Keep the handle-allocation path available behind --alloc-handle for follow-up
debugging, keep --raw-path as an explicit no-op for compatibility, and keep
--dir-handle N for testing relative paths against a handle that is valid in
the current connection.

This changes only the Linux smoke test; server AFP protocol behavior is
unchanged.
2026-05-30 03:52:35 +02:00
Mario Fetka
f6861ba3d6 tests: document AFP entry id smoke coverage
All checks were successful
Source release / source-package (push) Successful in 45s
Document the Linux AFP Entry ID smoke-test coverage after the endpoint was verified against the standard SYS volume paths.

The test exercises the WebSDK-documented NCP 0x23/0x0c AFP Get Entry ID From Path Name request by logging in through libncp, allocating a temporary directory handle for the volume root, and sending the relative path to the AFP endpoint.

Record the verified SYS:, SYS:PUBLIC, SYS:SYSTEM, and SYS:BURST cases, and describe the current stat-derived fallback Entry ID diagnostics so the result is not confused with persistent CNID/AppleDouble storage.

Keep the remaining AFP work tracked in TODO.md, including replacing the fallback with persistent CNID/directory-id mapping and extending tests when additional AFP subfunctions are implemented.

This is documentation-only and does not change AFP protocol behavior.
2026-05-30 03:38:10 +02:00
Mario Fetka
04e098efef tests: require login for AFP smoke test
All checks were successful
Source release / source-package (push) Successful in 47s
Open the libncp connection with login_necessary set to true.

ncpfs/libncp does not block individual NCP endpoints here. The problem was that ncp_initialize(..., 0, ...) deliberately clears the user name even when -S/-U/-P were supplied, leaving the connection unauthenticated. mars_nwe then rejects directory-handle allocation for non-login paths with Invalid Path before the AFP NCP 0x23/0x0c request is ever sent.

The AFP Entry ID smoke test needs normal file-service path access in order to allocate or use a directory handle before issuing the AFP request. Require a logged-in connection, while still allowing no-password test users via libncp's existing -n option.

This changes only the Linux smoke test; server AFP protocol behavior is unchanged.
2026-05-30 03:31:34 +02:00
Mario Fetka
d848dad93f tests: use mars_nwe dir handle call for AFP smoke
All checks were successful
Source release / source-package (push) Successful in 53s
Allocate the temporary directory handle for the AFP Entry ID smoke test through mars_nwe's old directory-handle endpoint instead of the NCP 87 namespace helper.

The AFP Get Entry ID From Path Name call expects a directory handle plus a relative path. The previous smoke-test variants tried to obtain that handle through libncp's namespace allocation helper, but mars_nwe currently rejects the NCP 87 DIRBASE volume-root form before the AFP request is sent, so no AFP diagnostics appear in the server log.

Use the old NCP 0x16/0x13 Allocate Temporary Directory Handle call that mars_nwe implements directly, passing a VOL: root path and then sending only the relative path to NCP 0x23/0x0c. Keep the existing deallocate path.

This changes only the Linux smoke test; server AFP protocol behavior is unchanged.
2026-05-30 03:23:31 +02:00
Mario Fetka
8887c4d7a5 tests: allocate AFP smoke handle from volume root
Resolve the volume name before allocating the temporary directory handle used by the AFP Entry ID smoke test.

ncpfs does not block the AFP endpoint. Its ncp_ns_alloc_short_dir_handle() helper sends the namespace-aware handle allocation request using the supplied directory style, volume, directory entry, and path tuple. The ncpfs tests allocate a handle for a volume root with NCP_DIRSTYLE_DIRBASE, a volume number, directory entry 0, and no encoded path, then use that handle with relative paths.

The smoke test was still trying to allocate the handle as a NOHANDLE path using a raw VOL: string. mars_nwe rejects that request before the AFP request is sent, so the test never reaches NCP 0x23/0x0c and no AFP diagnostics appear in the server log.

Look up the volume number with ncp_get_volume_number(), allocate the temporary handle as DIRBASE(volume, 0, NULL), and keep passing only the relative path to AFP Get Entry ID From Path Name.

This changes only the Linux smoke test; server AFP protocol behavior is unchanged.
2026-05-30 03:16:49 +02:00
Mario Fetka
d58d73b37f tests: encode AFP smoke handle paths through libncp
All checks were successful
Source release / source-package (push) Successful in 46s
Pass NCP_PATH_STD to ncp_ns_alloc_short_dir_handle() when the AFP Entry ID
smoke test allocates a temporary directory handle for a VOL: path.

The test already uses libncp to allocate the handle, but it passed the raw
"SYS:" bytes together with an explicit byte length. ncpfs helpers expect
NCP_PATH_STD when the caller wants libncp to encode a normal NetWare path into
the component-counted wire format. Sending the raw VOL: string made the server
reject the handle allocation with completion 0x98 before the AFP endpoint was
reached.

Keep the libncp handle allocation path, but let libncp encode the root volume
path the same way the ncpfs tools do. This changes only the Linux smoke test;
server AFP protocol behavior is unchanged.
2026-05-30 03:00:45 +02:00
Mario Fetka
cc98d22144 tests: allocate AFP smoke handles through libncp
All checks were successful
Source release / source-package (push) Successful in 51s
Use libncp\047s namespace-aware short directory handle helper in the AFP Entry ID smoke test instead of hand-building the old Allocate Temporary Directory Handle request.\n\nThe smoke test accepts NetWare-style VOL:PATH arguments, but NCP 0x23/0x0c AFP Get Entry ID From Path Name expects a directory handle plus a relative path. The previous test tried to allocate a temporary handle by issuing the old NCP 0x16/0x13 request directly, which failed with Invalid Path before the AFP endpoint was reached.\n\nMirror the ncpfs tools and call ncp_ns_alloc_short_dir_handle() for the volume root in the DOS namespace, then pass only the relative path to the AFP request. Keep deallocating the temporary handle after the request.\n\nThis changes only the Linux smoke test; server AFP protocol behavior is unchanged.
2026-05-30 02:56:59 +02:00
Mario Fetka
069bbba88c tests: resolve AFP smoke volume paths
All checks were successful
Source release / source-package (push) Successful in 47s
Teach the Linux AFP Entry ID smoke test to treat VOL:PATH arguments like normal NetWare paths instead of sending the full string as the AFP path component.

The WebSDK documents AFP Get Entry ID From Path Name as taking a NetWare directory handle plus a path string.  A user-supplied path such as SYS:PUBLIC therefore needs a directory handle for the SYS volume root and a relative AFP path of PUBLIC; sending SYS:PUBLIC as the AFP path with directory handle zero makes the server reject the request with Invalid Path before the actual AFP lookup is useful.

Use the existing ncpfs/libncp request path to allocate a temporary directory handle for the volume root when the test receives a VOL:PATH argument and no explicit --dir-handle was supplied.  Keep --raw-path for callers that want to send the path exactly as typed, and add --allow-invalid-path so negative path-resolution tests can distinguish Invalid Path from Invalid Namespace.

Also add failure diagnostics to the server-side AFP path lookup so unsupported-backend, boundary-check, path-resolution, and stat failures are visible in the mars_nwe log.

This changes only the Linux smoke test and debug logging; it does not change successful AFP protocol semantics.
2026-05-30 02:42:08 +02:00
Mario Fetka
b7999fcb7d tests: add Linux AFP entry id smoke test
All checks were successful
Source release / source-package (push) Successful in 46s
Add an optional Linux-side smoke test for the first implemented NetWare AFP endpoint.

The WebSDK documents NCP 0x2222/35/12 AFP Get Entry ID From Path Name as taking a NetWare directory handle and path string and returning a 32-bit AFP entry id. MARS-NWE now has a guarded implementation of that probe when the optional Netatalk/libatalk backend is compiled in, but exercising it does not require a real AppleTalk workstation.

Use the ncpfs/libncp client library as the test transport. ncpfs is commonly available on Linux mars_nwe test hosts and its NWRequestSimple() helper builds the same length-prefixed subfunction request format used by normal libncp callers. The test accepts standard ncpfs connection options such as -S, -U, -P, and -n, sends NCP 0x23/0x0c, and prints the returned entry id.

Keep the test out of normal builds behind MARS_NWE_BUILD_LINUX_TESTS because it depends on host ncpfs development headers/library and on a running server. Add an --allow-invalid-namespace mode so builds without the Netatalk backend can still run a negative smoke test and verify that AFP remains unavailable.

This adds test infrastructure only and does not change server protocol behavior.
2026-05-30 02:13:59 +02:00
Mario Fetka
ad153b88b9 nwconn: keep disk restriction scans local
All checks were successful
Source release / source-package (push) Successful in 51s
Keep NCP 0x16/0x20 Scan Volume User Disk Restrictions from linking nwconn against bindery database helpers.

The WebSDK documents the scan call as returning a sequence of Object ID / Restriction pairs, while the per-object NCP 0x16/0x29 query can be resolved through nwbind because it carries a concrete Object ID. The scan call is different: producing a quota-backed list requires iterating bindery user objects and reading each UNIX_USER property, which belongs to the nwbind/nwdbm side of the existing process split.

The previous implementation attempted that scan directly in nwconn and therefore referenced scan_for_obj() and nw_get_prop_val_by_obj_id(), which are provided by nwdbm and are not linked into the nwconn executable. This broke quota-enabled builds when the endpoint was compiled.

Return the SDK-compatible empty list after validating the volume, matching the existing non-quota behavior and the conservative behavior used by other open implementations. Leave real quota-backed scan enumeration as future nwbind-side work instead of pulling bindery database code into nwconn.

This fixes the build and preserves the documented endpoint shape; real quota scanning remains unimplemented.
2026-05-30 01:51:06 +02:00
Mario Fetka
eb2983bc1a nwconn: implement AFP entry id path lookup
All checks were successful
Source release / source-package (push) Successful in 48s
Wire NCP 0x23/0x0c AFP Get Entry ID From Path Name to a real path lookup when the optional Netatalk/libatalk backend is available.

The WebSDK documents NCP 0x2222/35/12 as converting a NetWare directory handle plus short-name path string into a unique 32-bit Macintosh file or directory Entry ID. The request carries the AFP subfunction, NetWare directory handle, path length, and path string; the reply carries the 4-byte AFP Entry ID. The SDK headers expose the same operation as AFPGetEntryIDFromPathName() and NWAFPGetEntryIDFromPathName(), and NWAFPSupported() uses this path-name probe to test AFP support.

Resolve the NetWare directory handle and path through the existing mars_nwe path machinery, require the optional libatalk backend before returning AFP success, and then ask libatalk for an AppleDouble/CNID-style id when available. If libatalk is present but the file has no stored id yet, return a deterministic stat-derived local entry id as a temporary fallback so the path-name probe can succeed without inventing NetWare directory base numbers.

Keep all other AFP subfunctions returning invalid namespace for now. They still need Finder Info, resource fork, AFP file information, fork open, and persistent CNID/directory-id support before they can safely report success.

Add the SDK request/reply semantics to the inline endpoint comments and keep the remaining AFP work tracked in TODO.md.

This implements only the AFP path-to-entry-id probe; it does not add general AFP file or resource-fork semantics yet.
2026-05-30 01:45:58 +02:00
Mario Fetka
0456882be3 nwconn: decode AFP subfunction diagnostics
All checks were successful
Source release / source-package (push) Successful in 47s
Decode the NCP 0x23 AFP subfunction number in diagnostics before rejecting the
call as an unavailable Mac namespace request.

The WebSDK documents the old NetWare AFP calls as NCP 0x2222/35 subfunctions,
and the SDK headers expose the same entry points through nwafp.h.  Record the
known subfunction names for AFP Delete, Get Entry ID From Name, Get Entry ID
From NetWare Handle, Rename, Open File Fork, Alloc Temporary Dir Handle, Get
Entry ID From Path Name, AFP 2.0 Create, Get/Set File Information, and Scan
File Information.

MARS-NWE still does not implement the per-volume Mac namespace semantics
required to return success for these calls.  Netatalk/libatalk can provide local
AppleDouble/Finder Info/resource-fork helpers, but mars_nwe must still decode
and answer the NetWare NCPs itself.

Keep returning invalid namespace for now, but make the rejected call visible in
the log so real client probes can be mapped to the SDK subcall that needs to be
implemented next.  Update TODO.md to track that the AFP dispatcher now has
subfunction-aware diagnostics.

This is diagnostics-only and does not change AFP protocol behavior.
2026-05-30 01:34:51 +02:00
Mario Fetka
771dfb0d39 Add Missing netatalk files
All checks were successful
Source release / source-package (push) Successful in 48s
2026-05-30 01:30:05 +02:00
Mario Fetka
13737d03c3 build: add optional Netatalk libatalk backend hook
Some checks failed
Source release / source-package (push) Failing after 41s
Add an opt-in CMake hook for Netatalk/libatalk and a small nwconn-side helper
layer for future AFP/Mac namespace work.

NetWare AFP NCP 0x23 calls still have to be decoded and answered by MARS-NWE;
libatalk is not used as an afpd proxy. Instead, expose local helper wrappers
that can read AppleDouble/Finder Info metadata and resource-fork sizes from a
backing Unix path when libatalk is available.

The WebSDK documents the AFP calls as NetWare server entry points for Mac
namespace semantics, and the SDK headers expose probes such as NWAFPSupported()
plus AFP entry-id and file-information calls. Those calls require AFP entry
IDs, Finder Info, resource forks, and per-volume Mac namespace state before
MARS-NWE can return success.

Keep NCP 0x23 returning invalid namespace for now, but record whether the
libatalk metadata backend was compiled in when rejecting AFP calls. Update
TODO.md to track the remaining NetWare AFP implementation work on top of the
new backend hook.

This adds build-time integration and local metadata helpers only; it does not
change AFP protocol behavior.
2026-05-30 01:25:55 +02:00
Mario Fetka
3421fceda3 nwconn: document TTS unavailable status
All checks were successful
Source release / source-package (push) Successful in 50s
Add WebSDK context to the Transaction Tracking System endpoint handling.

The WebSDK documents NCP 0x2222/34/00 TTS Is Available as a
completion-code-only status probe with no reply data. A completion code of
0x00 means Transaction Tracking Unavailable, 0xfd means Disabled, and 0xff
means Available. The SDK headers expose this call as NWTTSIsAvailable().

MARS-NWE does not implement TTS rollback semantics, transaction files,
transaction status tracking, or the begin/end/abort transaction state machine.
Keep reporting the documented unavailable status for the availability probe,
but leave state-changing TTS subfunctions unsupported rather than pretending
to start or complete transactions without rollback behavior.

lwared and the Rust nwserver implementation do not provide a fuller TTS
transaction implementation to mirror, so keep the remaining TTS work tracked
as deferred optional protocol work in TODO.md.

This preserves existing protocol behavior while documenting why the only
locally handled TTS subfunction is the availability probe.
2026-05-30 00:59:54 +02:00
Mario Fetka
98f45194b1 nwconn: scan volume user disk restrictions
All checks were successful
Source release / source-package (push) Successful in 49s
Wire NCP 0x16/0x20 Scan Volume's User Disk Restrictions to the existing
quota backend when quota support is available.

The WebSDK documents NCP 0x2222/22/32 as taking a Volume Number and a Sequence
value, and returning a Number Of Entries byte followed by up to twelve Object
ID / Restriction pairs. The Sequence starts at zero and is incremented by the
number of entries returned by previous calls. Restrictions are reported in 4K
blocks.

The SDK headers expose the same call as NWScanVolDiskRestrictions() and
NWScanVolDiskRestrictions2(). The Rust nwserver implementation and lwared both
validate the volume and return an empty list, which is compatible with an
unrestricted server but does not expose configured quotas.

Keep that empty-list behavior for non-quota builds. When QUOTA_SUPPORT is
enabled, scan bindery user objects, map each object through its UNIX_USER
property to a Unix uid, query nw_get_vol_restrictions(), and return entries for
users with an actual finite restriction. Use the request Sequence as an index
into the restricted-entry stream and return at most the SDK maximum of twelve
entries per reply.

Add the SDK request/reply semantics to the inline endpoint comment.

This enables the documented endpoint path while preserving the existing
no-restrictions result for builds without quota support.
2026-05-30 00:43:38 +02:00
Mario Fetka
297bb192f8 nwconn: document object disk restriction fallback
All checks were successful
Source release / source-package (push) Successful in 53s
Add SDK context to NCP 0x16/0x29 Get Object Disk Usage And Restrictions while
keeping the existing QUOTA_SUPPORT split intact.

The WebSDK documents NCP 0x2222/22/41 as taking a Volume Number and a high-low
Object ID, and returning Restriction and In Use values in 4K blocks. A
restriction of 0x40000000 means that the object has no disk restriction, and
invalid object IDs return success with no restriction and no space used.

With QUOTA_SUPPORT enabled, MARS-NWE routes the call through nwbind so the
object ID can be mapped to a Unix uid before nw_get_vol_restrictions() queries
the quota backend. With quota support disabled, keep the local SDK-compatible
unrestricted/no-use fallback so hosts without quota support do not need the
quota backend.

Add the SDK request/reply semantics to the inline endpoint comment and track
direct test coverage for both build modes in TODO.md.

This is documentation-only apart from renaming the debug message from DUMMY to
fallback, and preserves the build-time QUOTA_SUPPORT behavior.
2026-05-30 00:31:21 +02:00
Mario Fetka
c80861b92b nwconn: implement extracted base handle restore
All checks were successful
Source release / source-package (push) Successful in 54s
Wire NCP 0x16/0x17 Extract a Base Handle and NCP 0x16/0x18 Restore an
Extracted Base Handle to connection-local directory-handle state.

The WebSDK documents NCP 0x2222/22/23 as taking a DirectoryHandle and
returning a 14-byte save buffer composed of a 10-byte ServerNetworkAddress
plus a 4-byte HandleID. The same documentation describes NCP 0x2222/22/24 as
taking that saved ServerNetworkAddress/HandleID pair and returning a
NewDirectoryHandle plus AccessRightsMask.

The SDK headers expose these calls as NWSaveDirectoryHandle() and
NWRestoreDirectoryHandle(), with the save buffer explicitly documented as 14
bytes. The Rust nwserver and lwared references do not implement this older
save/restore pair, and newer clients typically use the normal allocate/set
directory-handle calls instead, so keep the MARS-NWE HandleID opaque and
connection-local rather than guessing a global NetWare directory-base number.

Store extracted base-handle IDs in a small per-connection table that records
the saved volume/path tuple. Extract requires a live permanent directory
handle, and Restore validates the saved server address against this server
before allocating a new permanent directory handle for the saved path.

Add the SDK request/reply semantics to the inline endpoint comments and remove
the corresponding TODO entry.

This enables the documented endpoint path while keeping the saved HandleID
conservative and private to MARS-NWE.
2026-05-30 00:12:31 +02:00