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.
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.
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.
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
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.
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.
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.
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
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.
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.
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.
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.
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.
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.
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.