Files
mars-nwe/TODO.md
2026-05-31 06:56:52 +02:00

35 KiB

TODO

This file collects follow-up work that is known but intentionally not part of the current patches. It is meant for project-level items that are too broad or too low-priority to keep as inline source TODO comments.

Server / NCP compatibility

Console privilege model

Current status:

  • NCP 23/200 Check Console Privileges is implemented as a protocol-compatible status check.
  • For now, console privileges are mapped to the existing supervisor-equivalence state computed for the connection.
  • Callers with supervisor equivalence get success; other callers get 0xc6 (No Console Rights).

Follow-up:

  • Add a real console-operator privilege model instead of treating console rights as identical to supervisor equivalence.
  • Decide where the console privilege map should live:
    • a bindery property,
    • a server configuration option,
    • or a small explicit internal list similar to queue operator handling.
  • Check how NetWare 3.x tools such as PCONSOLE, SYSCON, and console utilities expect console operators to be represented.
  • Keep NCP 23/200 as a completion-code-only endpoint; only the privilege source should change.

Queue spool path case handling

Current status:

  • Queue job paths can still be rebuilt from DOS/bindery path spelling such as SYS:SYSTEM/EPSON.QDR.
  • On a case-sensitive Unix filesystem this can differ from the existing directory, for example system/epson.qdr.

Follow-up:

  • Resolve queue job file paths case-insensitively in the queue connection/path resolver, or use the queue object's already-resolved Unix spool directory instead of rebuilding it from the DOS path.
  • Avoid creating duplicate directories that differ only by case.

NCP 17/4C test coverage

Current status:

  • NCP 17/4C List Relations of an Object is implemented server-side.
  • Existing DOS and Linux tools do not reliably trigger it for all useful set properties such as GROUP_MEMBERS and GROUPS_I'M_IN.

Follow-up:

  • Add a small direct test utility to mars-dosutils / NWTESTS that sends NCP 17/4C directly.
  • Suggested test cases:
    • TESTGRP1 type 0x0002, property GROUP_MEMBERS
    • TESTGRP2 type 0x0002, property GROUP_MEMBERS
    • MARIO type 0x0001, property GROUPS_I'M_IN
    • NOPASSUSER type 0x0001, property GROUPS_I'M_IN
    • GUEST type 0x0001, property GROUPS_I'M_IN

NCP endpoint SDK documentation / stub audit

Current status:

  • Several legacy NCP endpoints in src/nwconn.c are implemented only as disabled stubs, explicit 0xfb unsupported replies, or success/no-op dummies.
  • The known candidates now have inline SDK-context comments so future work can start from the documented wire semantics instead of from guesswork.

Follow-up:

  • Implement or deliberately reject remaining endpoint gaps after client evidence or direct protocol tests.
  • Keep SDK details close to the corresponding endpoint in nwconn.c, and keep broader prioritization/status here in TODO.md.

NCP endpoint audit tracking

Current status:

  • src/nwconn.c contains a mix of implemented, forwarded, partial, dummy, and intentionally unsupported NCP endpoints.
  • Endpoint comments should be aligned with the Novell SDK Web documentation, SDK headers, the Rust nwserver implementation, lwared, and the existing mars_nwe admin/Pascal code where those sources cover the same call.

Follow-up:

  • Keep inline TODO: comments only where endpoint behavior is incomplete, approximate, intentionally dummy/no-op, or still needs SDK layout verification.
  • Mirror every real incomplete endpoint in this file so follow-up work remains visible outside the source code.
  • Do not treat every return(-1) in nwconn.c as incomplete: many of those paths intentionally forward bindery/global-server work to nwbind.

NCP synchronization endpoint audit

Current status:

  • The old NCP synchronization endpoint family in src/nwconn.c is now annotated with Novell SDK endpoint names.
  • The existing source already marked this area as not well tested, so the comments intentionally keep that compatibility warning visible.
  • NCP 0x03, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x1a, and 0x1e have local implementations.

Follow-up:

  • Verify the implemented file/logical-record/physical-record calls against the Novell SDK request/reply layouts and a real DOS requester or direct test caller.
  • Continue direct requester or NWTESTS coverage for the file, logical-record, and physical-record synchronization calls that are now wired.
  • Verify timeout and error-code behavior for set-oriented locking calls against a real requester, especially where MARS-NWE currently relies on the existing underlying share implementation.

AFP Set File Information timestamp coverage

Current status:

  • AFP Set File Information (0x09) and AFP 2.0 Set File Information (0x10) now accept the file modification timestamp bitmap (0x0010) for path-backed file requests.
  • Timestamp writes are routed through the existing NetWare nw_utime_node() helper so trustee Modify rights and the established Unix utime(2) fallback behavior are reused instead of inventing AFP-specific timestamp handling.
  • The AFP smoke helper verifies the AFP date/time fields via the follow-up Get File Information response, and the smoke suite also records stat -c %Y for the backing Unix file.

Follow-up:

  • Add directory timestamp handling once the shared AFP path/object resolver grows directory-specific Set File Information semantics.
  • Keep create/access/backup timestamp writes disabled until their exact AFP to NetWare/Unix metadata mapping is deliberately wired and tested.
  • Keep Delete/Rename/Create/Remove for later patches that can reuse the existing NetWare server helpers and trustee checks.

Extended volume information field mapping

Current status:

  • NCP 0x16/0x33 Get Extended Volume Information returns the documented NWVolExtendedInfo reply and fills the core fields that can be derived from generic Unix filesystem statistics.
  • NetWare-specific fields that MARS-NWE does not currently model are returned as zero for now instead of guessed values.

Follow-up:

  • Fill additional NWVolExtendedInfo fields when reliable data is available from the backing filesystem or from MARS-NWE metadata.
  • Candidate fields include suballocation, deleted-file/limbo accounting, compression counters, migration counters, EA counters, Directory Services object id, and last-modified timestamp data.
  • Treat compression-related fields as real follow-up work rather than permanent zeroes; populate them only when the backing filesystem exposes trustworthy compressed-file or compressed-block accounting.

Object disk restriction fallback coverage

Current status:

  • NCP 0x16/0x29 Get Object Disk Usage And Restrictions keeps the existing QUOTA_SUPPORT split.
  • With quota support enabled, the endpoint is routed through nwbind so the bindery Object ID can be mapped to a Unix uid before querying the quota backend.
  • Without quota support, the endpoint returns the SDK-compatible fallback: unrestricted (0x40000000) and no space in use.

Follow-up:

  • Add direct tests for both build modes.
  • Verify the quota-enabled path against a real Unix quota setup.
  • Verify that the quota-disabled fallback remains compatible with requesters and with the WebSDK rule for invalid object IDs.

Printing / Queue backend

Q_UNIX_PRINT backend status

Current status:

  • Queue metadata handling and the Q_UNIX_PRINT backend are intentionally separate.
  • The backend can already call /usr/bin/lp, lpr, or a custom script.

Follow-up:

  • Improve logging around queue job submission to the Unix print command.
  • Capture and expose backend exit status where possible.
  • Consider direct CUPS integration only if MARS_NWE needs CUPS job IDs, cancellation, or status polling. Do not add a hard CUPS dependency for basic queue compatibility.

Transaction Tracking System (TTS)

Current status:

  • NCP 0x22/0x00 TTS Is Available reports the WebSDK-documented unavailable status.
  • MARS-NWE does not currently implement TTS rollback semantics, transaction files, transaction status tracking, or the begin/end/abort transaction state machine.
  • Other TTS subfunctions remain unsupported instead of pretending to succeed without real transaction tracking.

Follow-up:

  • Implement TTS only if a concrete client requires it.
  • Treat this as a real transaction subsystem, not as a completion-code shim: the WebSDK TTS calls include begin/end/abort transaction, status, threshold, and control/statistics operations.

AFP / Mac namespace backend

Current status:

  • NCP 0x23 still returns invalid namespace for AFP calls that are not implemented yet.
  • AFP Get Entry ID From Path Name is implemented when the optional mars_nwe AFP xattr metadata backend is available. Entry IDs are now derived first from existing mars_nwe NetWare namespace/basehandle state rather than from a parallel AFP/stat fallback generator. AFP smoke coverage exists in tests/afp/afp_entry_id_smoke; the latest full-suite run against SYS:PUBLIC/pmdflts.ini returned entry_id=0x00000004.
  • AFP Get Entry ID From Name is implemented for the same path-backed smoke mode. AFP smoke coverage uses tests/afp/afp_entry_id_smoke --from-name; the identity source follows the same NetWare namespace/basehandle path as Entry ID From Path Name.
  • AFP Get File Information is implemented for read-only path-based requests. AFP smoke coverage exists in tests/afp/afp_file_info_smoke and has been verified against SYS:, SYS:PUBLIC, SYS:SYSTEM, and SYS:BURST. The same test verifies the AFP 2.0 Get File Information subfunction via --afp20 against the same paths, using the same path-backed read-only reply for now. The current reply fills stat/mars_nwe AFP xattr-derived fields and leaves persistent CNID Parent ID / fuller Mac namespace metadata as future work.
  • AFP Scan File Information (0x0a) and AFP 2.0 Scan File Information (0x11) are implemented for path-backed read-only directory scans. Linux smoke coverage exists in tests/afp/afp_scan_info_smoke; the helper defaults to the AFP 2.0 subfunction and uses --afp10 for the older endpoint. Runtime coverage has been verified against SYS:PUBLIC by walking multiple directory entries with the returned next_last_seen AFP Entry ID continuation value. The verified AFP 2.0 and older 0x0a first records now expose NetWare namespace/basehandle-derived Entry IDs. The latest full-suite run against SYS:PUBLIC returned next_last_seen=0x00000004 and entry_id=0x00000004 for the first scanned record while preserving the expected file metadata.
  • AFP Get Entry ID From NetWare Handle is implemented for read-only data-fork file handles that are opened in the same client connection. Linux smoke coverage uses tests/afp/afp_entry_id_smoke --from-handle. The latest full-suite run verified SYS:PUBLIC/pmdflts.ini, returning volume 0, fork=0, and the same NetWare namespace/basehandle-derived entry_id=0x00000004 as the path-backed lookup.
  • AFP Open File Fork is implemented for the same path-backed smoke subset. Raw VOL:-style paths resolve the effective NetWare volume from the path prefix instead of assuming volume 0, so the same smoke path can cover SYS: and non-SYS: volumes. It opens only the data fork read-only and returns a normal six-byte NetWare file handle plus the current data-fork length; the AFP smoke helper tests/afp/afp_open_file_fork_smoke closes the returned handle in the same connection. Runtime smoke coverage is green for SYS:PUBLIC/pmdflts.ini (fork_len=8161) and SYS:PUBLIC/ohlogscr.bat (fork_len=1296) using fork=0 and read access 0x01. The smoke suite now also asserts that write-open requests fail with completion 0x84 and resource-fork opens fail with completion 0x9c, keeping the current unsupported cases explicit until AppleDouble/resource-fork, AFP write-open, and persistent CNID/base-ID semantics are available.
  • AFP Alloc Temporary Directory Handle is implemented for the same path-backed smoke subset. Raw VOL:-style paths resolve the effective NetWare volume from the path prefix instead of assuming volume 0. Linux smoke coverage exists in tests/afp/afp_temp_dir_handle_smoke; runtime smoke coverage is green for SYS:, SYS:PUBLIC, SYS:SYSTEM, and SYS:BURST. The helper returns a temporary NetWare directory handle plus the AFP one-byte access-rights mask and immediately deallocates the handle in the same connection. Server diagnostics log the wider internal NetWare effective-rights mask, so privileged directories can show rights=0x1ff while the client prints rights=0xff. Entry-ID-only allocation remains TODO until persistent CNID/base-ID lookup exists.
  • AFP Set File Information (0x09) and AFP 2.0 Set File Information (0x10) now require the fixed WebSDK/NWAFP request layouts for path-backed file metadata smoke writes. The legacy request uses path_len at offset 54; the AFP 2.0 request uses ProDOSInfo at offsets 54..59 and path_len at offset 60. The compact mars_nwe-only smoke packet layout has been removed. The covered bitmaps are FinderInfo (0x4000), Attributes (0x0100), Access Date/Time (0x0400), Create Date/Time (0x0800), Modify Date/Time (0x1000), and Backup Date/Time (0x2000). FinderInfo is stored in org.mars-nwe.afp.finder-info; Hidden/System/Archive attributes are mapped to the existing NetWare attribute path; org.mars-nwe.afp.attributes is only for future AFP-only bits that are not NetWare attributes. Create and Backup Date/Time use the existing mars_nwe NetWare metadata helpers; Access Date/Time uses the normal file atime path; and Modify Date/Time uses the shared timestamp helper. Linux smoke coverage exists in tests/afp/afp_set_file_info_smoke, which now always reports layout=websdk and verifies the result through AFP 2.0 Get File Information. Runtime status: the WebSDK-layout-only smoke run for SYS:PUBLIC/pmdflts.ini completed with failures=0, including legacy 0x09 and AFP 2.0 0x10 FinderInfo, Hidden/System/Archive set/clear, Access/Create/Modify/Backup timestamp probes, and the NOPASSUSER Modify-rights negative probes.
  • The AFP dispatcher now decodes the WebSDK/NWAFP subfunction number in diagnostics so real client probes can be mapped to the corresponding AFP call before implementation work starts.
  • AFP metadata now uses the standalone mars_nwe AFP xattr backend. There is no Netatalk/libatalk dependency for Entry ID, FinderInfo, or AFP-only attribute storage; AFP protocol support remains limited to the endpoints explicitly implemented in nwconn.c and guarded by the existing build configuration. Runtime status after the standalone backend change: the full AFP smoke suite completed with failures=0, including path-backed and entry-id-only Open File Fork, FinderInfo xattr verification, absent optional AFP-only attributes xattr, and NetWare-backed Hidden/System/Archive/timestamp probes.
  • Existing mars_nwe private xattr payloads use the org.mars-nwe.<domain>.* namespace (org.mars-nwe.netware.archive and org.mars-nwe.netware.fileinfo) rather than the unreleased test-only user.mars_nwe.* names. There is no legacy read fallback because the old names never shipped outside local test systems. On Linux, mars_nwe's local xattr helper maps source-level org.mars-nwe.<domain>.* names to the portable user.org.mars-nwe.<domain>.* storage namespace, mirroring the xattr abstraction used for Apple metadata.
  • NetWare AFP calls are NCP entry points for Mac namespace semantics on a NetWare volume, not transport-level AFP proxy calls to afpd.
  • AFP Get DOS Name From Entry ID (0x12) is implemented as a conservative read-only reverse lookup that first uses the existing mars_nwe map_directory_number_to_path() namespace/basehandle path for directory objects. Regular file Entry IDs stay on the cached AFP/fallback path until a reliable file-object reverse mapper is available. The legacy nwatalk_get_entry_id() volume scan remains as the fallback for cached AFP file IDs.

Follow-up:

  • Implement the NetWare AFP NCP calls locally, using mars_nwe AFP xattr helpers rather than proxying requests to afpd. Create Directory, Create File, AFP Delete, and AFP Rename are now implemented through existing mars_nwe create/remove/rename helpers and covered by Linux smoke tests.
  • Candidate future AFP-only pieces should stay under org.mars-nwe.afp.*. FinderInfo and regular-file Entry IDs are already implemented there. Do not add NetWare semantics such as Hidden/System/Archive attributes or timestamps to AFP xattrs; route them through the existing mars_nwe NetWare helpers.
  • Keep returning invalid namespace for AFP calls that still lack a real per-volume Mac namespace/AFP metadata layer. Do not return success for additional AFP calls without data/resource fork and Finder Info semantics.
  • AFP Entry IDs now prefer the existing mars_nwe NetWare namespace/basehandle mapping for directories. Regular files use mars_nwe AFP xattr Entry IDs for entry-id-only reverse lookup. AFP must not grow a second mars_nwe object-id resolver in parallel to the existing namespace machinery.
  • The full smoke suite verifies path-backed file identity end to end: Entry ID From Path Name, Entry ID From NetWare Handle, Get File Information, Set File Information verification, and Get DOS Name From Entry ID all returned or consumed a cached AFP/fallback file ID for the sample SYS:PUBLIC/pmdflts.ini path, while directory-scan entries continue to use the existing namespace/basehandle identity. AFP directory-scan continuation remains directory iteration based: 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. The latest full smoke run also verified AFP Delete cleanup for Create Directory/Create File, AFP Rename for both directories and files, and WebSDK-layout-only Set File Information for FinderInfo, attributes, and timestamps; it ended with failures=0. FinderInfo plus the Finder Hidden/System/Archive AFP attributes now have deliberately narrow write paths through AFP Set File Information 0x09 and AFP 2.0 Set File Information 0x10; CNID allocation and broader AFP metadata writes still need a deliberate write-safe design.
  • Put additional future mars_nwe-owned AFP metadata under org.mars-nwe.afp.* (or a compact org.mars-nwe.afp.metadata record) and keep externally owned Apple metadata under its own keys.
  • Extend the Linux AFP smoke tests once additional AFP subfunctions are implemented, especially Finder Info updates, fork open/read/write paths, resource-fork handling, and broader directory-scan edge cases.

AFP implementation convergence plan

Current status:

  • The AFP/NWAFP work is now broad enough that future endpoint patches should treat AFP as an Apple-facing adapter over the existing mars_nwe NetWare server machinery rather than as a parallel file server implementation.
  • The safe baseline already includes path-backed Entry ID, Get/Scan File Information, temporary directory handles, read-only data-fork Open File Fork, narrow Set File Information metadata writes, NetWare-backed Archive attribute mapping, Modify timestamp writes through nw_utime_node(), and a conservative Get DOS Name From Entry ID reverse lookup.
  • The Get DOS Name From Entry ID helper now returns the canonical DOS namespace spelling from the existing mars_nwe namedos.c alias builder. The follow-up smoke run confirms PUBLIC/PMDFLTS.INI for SYS:PUBLIC/pmdflts.ini, replacing the earlier raw Unix/realcase public/pmdflts.ini result.

Design rule:

  • AFP request handlers should parse the WebSDK/NWAFP request, resolve volume, path, directory handle, or entry id to an existing mars_nwe object, call the established NetWare helper, and translate the result into the AFP reply layout.
  • Do not introduce direct open(2), unlink(2), rename(2), mkdir(2), utime(2), attribute, trustee, or directory-scan logic inside AFP handlers when a mars_nwe helper or wrapper already exists.
  • Only keep AFP-specific storage for metadata that has no NetWare equivalent, such as FinderInfo, AFP Entry IDs/CNIDs, and narrowly scoped AFP-only attributes that are deliberately not mapped to NetWare attributes yet.

Refactor/wrapper follow-up:

  • Continue reusing the existing mars_nwe volume, namespace, basehandle, and directory-handle helpers for AFP object lookup. Do not add an AFP-local object resolver where conn_get_kpl_unxname(), nw_vol_inode_to_handle(), map_directory_number_to_path(), or related namespace helpers already cover the case.
  • Route all AFP writes through existing mars_nwe policy checks before changing metadata. Archive and Modify timestamp already do this through NetWare helpers. FinderInfo and AFP-only Hidden/System xattr writes are now gated by the same trustee/effective-rights Modify policy before the AFP metadata xattrs are updated.
  • Continue moving AFP-visible NetWare attributes onto the existing NetWare attribute store. Hidden, System, and Archive are mapped to FILE_ATTR_H, FILE_ATTR_S, and FILE_ATTR_A; ReadOnly, ExecuteOnly, and Shareable still need either a real mapping through existing attribute helpers or an explicit unsupported result.
  • Extend Set File Information timestamps only through existing mars_nwe helpers: Modify is routed through nw_utime_node(), Access through the existing st_atime/utime() path, and Create/Backup through the existing nwarchive.c metadata helpers.
  • Normalize Get/Scan File Information so each field comes from the existing mars_nwe source of truth where possible: NetWare attributes, file size, timestamps, owner information, archive date/time, FinderInfo, resource-fork size, and Entry ID/CNID metadata. AccessPrivileges are now derived from tru_get_eff_rights() instead of static AFP masks and have readonly smoke coverage under a temporary [RF] trustee assignment.
  • Revisit Scan File Information after the resolver work and prefer mars_nwe's existing directory/search machinery over the current AFP-local directory walk for search attributes, namespace filtering, and multi-record replies.
  • The current Get DOS Name From Entry ID path first uses the existing map_directory_number_to_path() namespace/basehandle lookup and only falls back to the legacy AFP metadata volume walk when necessary. Future CNID work should plug into that same resolver order rather than reintroducing a parallel path database.

AFP Set File Information metadata-rights convergence:

  • AFP FinderInfo writes and AFP-only Hidden/System attribute xattr writes no longer bypass NetWare policy just because their storage is AFP-specific. afp_set_file_information() now checks the resolved file through the existing trustee/effective-rights Modify policy before writing org.mars-nwe.afp.* metadata.
  • Archive continues to route through the NetWare attribute helper (FILE_ATTR_A), and Modify timestamp continues to route through nw_utime_node(). The new check only covers metadata that has to remain AFP-specific, keeping AFP as an Apple-facing adapter over mars_nwe policy rather than a parallel file server.
  • The Linux AFP smoke suite now has optional negative coverage for this policy gate. With --readonly-user NOPASSUSER --readonly-no-password, the suite can run FinderInfo, Hidden, and System writes as a user that is expected to lack Modify rights and assert completion 0x8c. With --prepare-readonly-rights, the suite uses the existing ncpfs nwgrant/nwrevoke trustee utilities to grant only read/file-scan rights ([RF] by default) before the negative probe and revoke the explicit trustee assignment afterwards.
  • Runtime status: the negative smoke has been verified with NOPASSUSER as a no-password test user. The suite temporarily granted [RF] on SYS:PUBLIC/pmdflts.ini, confirmed FinderInfo, Hidden, and System Set File Information requests are rejected with completion 0x8c, and then successfully revoked the temporary trustee assignment. The same run ended with failures=0, preserved the final TEXT/MARS FinderInfo xattr, kept org.mars-nwe.afp.attributes clear after the attribute cleanup probes, and left the Modify timestamp at the expected smoke value.

Endpoint order:

  • AFP Create Directory (0x01) and AFP 2.0 Create Directory (0x0d) are now routed through the existing NetWare directory-create helper for temporary smoke paths. The Linux smoke suite creates both a legacy and AFP 2.0 directory under the tested parent and verifies the returned namespace-derived Entry ID. AFP Delete is now used for server-side cleanup so the suite no longer relies on local Unix rmdir permissions.
  • Runtime status: the create-directory smoke has been verified with failures=0. The latest run created SYS:PUBLIC/afptst2 through legacy AFP Create Directory (0x01) and SYS:PUBLIC/afptst22 through AFP 2.0 Create Directory (0x0d), with both probes returning and re-verifying Entry ID 0x00000005, then removed both objects through AFP Delete.
  • AFP Create File (0x02) and AFP 2.0 Create File (0x0e) are now routed through the existing NetWare file-create path for temporary smoke files. The AFP smoke helper creates both legacy and AFP 2.0 files under the tested parent, verifies the returned AFP file ID with Entry ID From Path Name, and removes them through AFP Delete.
  • Runtime status: the create-file smoke has been verified with AFP Delete cleanup. The latest run created SYS:PUBLIC/atst2 through legacy AFP Create File (0x02) and SYS:PUBLIC/atst22 through AFP 2.0 Create File (0x0e); both returned nwatalk/fallback AFP file IDs (0x53c18b6e and 0x755cda24), were re-verified with AFP Entry ID From Path Name, and were removed through AFP Delete.
  • AFP Delete (0x03) is implemented through the existing NetWare delete/erase policy path. It is used by the smoke suite for pre-test cleanup and post-test cleanup of Create Directory, Create File, and Rename paths.
  • AFP Rename (0x07) is implemented through the existing NetWare rename/move paths. Directory rename uses the directory-aware move helper, while file rename uses the NetWare file move path with file-only search attributes so regular files are not filtered out by the directory attribute bit.
  • Runtime status: the rename smoke has been verified with failures=0. The run created and renamed SYS:PUBLIC/d22240 to SYS:PUBLIC/d22240r, preserving the namespace-derived directory Entry ID 0x00000005; it also created and renamed SYS:PUBLIC/m22248 to SYS:PUBLIC/m22248r, preserving the nwatalk/fallback AFP file Entry ID 0x78da3728. Both renamed objects were cleaned up through AFP Delete.
  • Keep Get Macintosh Info On Deleted File (0x13) for last.

Deferred / optional protocol work

  • Basic Packet Burst file transfer support is implemented and verified with a diagnostics-enabled DOS client test.
  • Packet Burst support is built by default, but runtime use remains controlled by nwserv.conf.
  • Packet Burst/NDS fragmentation support remains out of scope unless a concrete client requires it.

AFP attribute convergence correction

AFP Set/Get File Information attribute handling must follow the WebSDK attribute word rather than the earlier low-bit smoke placeholders. The documented SetInfo request bitmap uses 0x0100 for Attributes, 0x1000 for Modify Date/Time, and 0x4000 for FinderInfo. The returned/set Attributes word uses 0x0200 Hidden, 0x0400 System, and 0x2000 Archive. These are mapped through the existing NetWare attribute store (FILE_ATTR_H, FILE_ATTR_S, FILE_ATTR_A) so AFP does not keep parallel xattr-only copies for those NetWare attributes. --invisible remains only a smoke-helper compatibility alias for Hidden.

Runtime status: the WebSDK attribute-bit smoke run is verified with failures=0. The suite confirmed Hidden set/clear as 0x0200/0x0000, System set/clear as 0x0400/0x0000, and Archive set/clear as 0x2000/0x0000. The same run confirmed the WebSDK SetInfo bitmaps 0x0100 for Attributes, 0x1000 for Modify Date/Time, and 0x4000 for FinderInfo. Because all tested attribute bits are now stored through the NetWare attribute path, user.org.mars-nwe.afp.attributes may be absent in the final xattr dump; this is expected and no longer counts as a smoke failure.

AFP Backup Date/Time convergence

AFP Set File Information now treats the WebSDK 0x2000 request bitmap as the Backup Date/Time field, distinct from the 0x2000 Archive attribute bit inside the Attributes word. The timestamp payload is routed through the existing mars_nwe_set_archive_info() helper in nwarchive.c, so the data is stored in org.mars-nwe.netware.archive together with the NetWare archive date/time metadata rather than in an AFP-specific xattr. AFP Get/Scan File Information merge the stored archive date/time back into the 120-byte AFP information record.

This keeps the split explicit: Archive as an attribute is FILE_ATTR_A in the NetWare attribute store; Backup Date/Time is archive metadata in nwarchive.c; FinderInfo remains AFP metadata in org.mars-nwe.afp.finder-info. The Linux smoke suite covers --backup-time-only --backup-time-epoch and dumps user.org.mars-nwe.netware.archive so runtime reports show the underlying mars_nwe storage path.

Runtime status: the Backup Date/Time smoke run is verified with failures=0. The suite confirmed AFP Set File Information Backup Timestamp using bitmap 0x2000 and reported backup=0x576eb9aa for epoch 1700000000. The same run confirmed the backing mars_nwe metadata xattr: user.org.mars-nwe.netware.archive=0x01036e57aab900000000. That confirms the intended split: Archive as a file attribute stays on the NetWare attribute path, while Backup Date/Time is stored by nwarchive.c.

AFP Create and Access Date/Time convergence

AFP Set File Information now accepts the WebSDK 0x0800 Create Date/Time request bitmap and routes the payload through the existing mars_nwe_set_file_info() helper in nwarchive.c. AFP Get/Scan File Information read the same mars_nwe_get_file_info() metadata and fall back to the historical Unix timestamp source when no NetWare file-info metadata is stored. The backing xattr is user.org.mars-nwe.netware.fileinfo; no AFP-specific xattr is introduced for this NetWare-semantic field.

AFP Set File Information also accepts the WebSDK 0x0400 Access Date/Time request bitmap. Access timestamps are routed through the existing POSIX st_atime/utime() path, preserving st_mtime and enforcing trustee Modify rights before updating the file. This keeps Access Date/Time out of nwarchive.c and out of AFP-only xattrs, matching the existing mars_nwe NetWare file-info model.

Runtime status: the combined AFP timestamp smoke run is verified with failures=0. The suite confirmed AFP Set File Information Access Timestamp using bitmap 0x0400 and AFP Set File Information Create Timestamp using bitmap 0x0800, both for epoch 1700000000 with the returned AFP date 0x576e. The same run confirmed the Create Date/Time backing metadata xattr user.org.mars-nwe.netware.fileinfo=0x01036e57aab90000000000000000, while Access Date/Time remained on the normal file atime path and did not create an AFP metadata xattr.

AFP metadata entry-id resolver convergence

AFP Get File Information and AFP Set File Information now accept entry-id-only requests for regular files whose AFP ID is present in the mars_nwe AFP entry-id xattr metadata. The shared resolver converts the AFP file Entry ID back to a normal VOL:PATH string and then routes the operation through the existing NetWare metadata paths. Regular file Entry IDs are not treated as DOS namespace directory numbers.

Runtime status: the full AFP smoke suite is verified with failures=0 after adding entry-id-only coverage for Get File Information, Set File Information FinderInfo, and Set File Information Hidden. The verified run used AFP Entry ID 0x05aaace0 for SYS:PUBLIC/pmdflts.ini; the server log shows the resolver feeding SYS:PUBLIC/PMDFLTS.INI into Get/Set File Information before applying the normal FinderInfo and NetWare attribute paths.

AFP Set File Information WebSDK layout convergence

AFP Set File Information now requires the fixed WebSDK/NWAFP packet layouts for both legacy 0x09 and AFP 2.0 0x10. The earlier compact mars_nwe smoke layout was removed because it was not wire-compatible. Legacy requests carry Attributes at offset 8, Create Date at 10, Access Date at 12, Modify Date/Time at 14/16, Backup Date/Time at 18/20, FinderInfo at 22, and path_len at 54. AFP 2.0 requests use the same fixed metadata fields, include ProDOSInfo at 54..59, and carry path_len at 60.

Runtime status: the WebSDK-layout-only Set File Information smoke run is verified with failures=0. The suite reported layout=websdk for both AFP 2.0 0x10 and legacy 0x09 FinderInfo writes, Hidden set/clear, System set/clear, Archive set/clear, and Access/Create/Modify/Backup timestamp probes against SYS:PUBLIC/pmdflts.ini. The verified run used AFP Entry ID 0x42ede1c8, kept FinderInfo as TEXTMARS, confirmed the final AFP-only attributes xattr may be absent when no AFP-only bits remain set, and confirmed NetWare file-info/archive metadata through the existing user.org.mars-nwe.netware.fileinfo and user.org.mars-nwe.netware.archive xattrs.

AFP Get/Scan AccessPrivileges convergence:

  • AFP Get File Information and AFP Scan File Information now use the same trustee/effective-rights source when filling the WebSDK AccessPrivileges word. The old static file/directory masks have been replaced with mapping from tru_get_eff_rights() to Read, Write, Open, Create, Delete, Parental, Search, and Modify File Status Flags.

  • File-level readonly attributes still suppress write/delete style AFP privileges for file replies, while directories expose directory-appropriate parental/search/status bits based on the effective trustee rights.

  • Runtime status: the AFP smoke suite verified the mapping with --readonly-user NOPASSUSER --readonly-no-password --prepare-readonly-rights. The suite granted [RF] on SYS:PUBLIC/pmdflts.ini, confirmed the readonly Get File Information probe reported rights=0x0500, checked that Read was set and Write/Modify Status were clear, then revoked the temporary trustee assignment. The same run ended with failures=0.

  • Follow-up from AFP namespace entry ID smoke: directory AFP entry IDs may use NetWare namespace/basehandles, but regular files currently keep nwatalk or fallback AFP IDs because the existing directory-number reverse mapper is not a reliable file-entry reverse mapper on DOS namespace volumes.