# 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`. - When an endpoint returns to `nwbind`, keep the audit paired: the dispatcher comment in `nwconn.c` should name the handoff, and the concrete parser in `nwbind.c` should carry the request/reply layout. This was rechecked for the currently documented forwarded paths: message group `0x2222/21`, quota prehandling in Directory Services `0x2222/22`, File Server Environment `0x2222/23`, End of Job `0x2222/24`, Logout `0x2222/25`, and Semaphore `0x2222/32`. ### NCP endpoint layout audit (version-bucketed compatibility) Current status: - The default NCP endpoint audit is scoped to compatibility calls through NetWare 3.x. NetWare 1.x/2.x legacy calls are part of that compatibility target when they are documented, but they should be kept in their own buckets instead of being mixed into the 3.x/default list. - Bucket endpoints by the oldest generation that documents or requires them: 1.x/2.x legacy first, then remaining through-3.x compatibility calls, then a separate NetWare 4.x planning/stub bucket for later work. - Keep SDK request/reply details close to the corresponding endpoint in the source file that handles the call. If `nwconn.c` forwards a group to `nwbind.c`, document the handoff in `nwconn.c` and the concrete subfunctions in `nwbind.c`. - Documentation-only audit patches should not change parsing or reply behavior; record observed differences here for later implementation or compatibility testing. Compare against the local NDK/Core Protocols PDF, the WebSDK HTML, and the uploaded SDK include prototypes when those sources cover the call. - `MARS_NWE_4` is hard-disabled in `include/config.h.cmake`. Do not move or wrap already implemented code just because it is 4.x-era; only new, unimplemented 4.x stubs should be guarded with `#if MARS_NWE_4`. #### Version buckets for endpoints documented so far NetWare 1.x/2.x legacy bucket: - Old direct file/logical/physical synchronization calls: `0x2222/01` through `0x2222/0e` where documented by the legacy SDK/PDF. - Old direct utility/message handoff calls around `0x2222/12` through `0x2222/15`, including the 1.x/2.x-compatible broadcast subfunctions handled in `src/nwbind.c`. - Older directory-handle compatibility calls that the local PDF marks as early NetWare compatibility, especially `0x2222/22/17` and `0x2222/22/18`. NetWare 3.x/default compatibility bucket: - Remaining documented `0x2222/22` Directory Services calls through the NetWare-3.x-compatible namespace/directory range ending at `22/48`, unless a specific call is proven to belong to the older bucket above. - Salvage compatibility is part of this default bucket where the old `22/27`, `22/28`, `22/29` bridges map to the newer salvage backend. NetWare 4.x planning/stub bucket: - `0x2222/22/50 Get Object Effective Rights for Directory Entry` and `0x2222/22/51 Get Extended Volume Information` are documented by the local NDK/Core Protocols PDF as NetWare 4.x/5.x calls and are also visible through the uploaded WebSDK/include material (`NWGetObjectEffectiveRights`, `NWGetExtendedVolumeInfo`). - MARS-NWE already has active compatibility implementations for these two calls; leave that code in place. Track them in the 4.x bucket for future cleanup, tests, and field mapping rather than moving them into the default 3.x TODO list or hiding them behind `MARS_NWE_4`. - Any additional not-yet-implemented 4.x/OES/MOAB endpoint discovered later should be documented as a plan and, if a source stub is useful, guarded with `#if MARS_NWE_4` while the macro remains `0`. #### Old direct file/logical/physical synchronization calls Current status: - The old direct synchronization family in `src/nwconn.c` is annotated with Novell SDK endpoint names and request-layout notes. - `NCP 0x01 File Set Lock (old)` and `NCP 0x02 File Release Lock` are documented in the SDK but are not implemented in MARS-NWE yet. Inline documentation and commented case/break stubs are present in `src/nwconn.c`. - `NCP 0x03 Log File (old)` is implemented, but still belongs on the audit list because the original source already marked this old log/lock area as not well tested. - `NCP 0x04 Lock File Set (old)` and `NCP 0x6a Lock File Set` share the current implementation. The SDK documents the old `0x04` timeout word as Lo-Hi and the newer `0x6a` timeout word as Hi-Lo; MARS-NWE currently reads the shared field with `GET_BE16()`. This is documented inline but not changed yet. - `NCP 0x05 Release File (old)` and `NCP 0x07 Clear File (old)` have request parsing that matches the documented old header offsets. - `NCP 0x06 Release File Set` and `NCP 0x08 Clear File Set` are implemented, but the SDK request contains a `LockFlag` byte that the current code does not read. This parser difference is documented inline but not changed yet. - `NCP 0x09 Log Logical Record (old)`, `NCP 0x0a Lock Logical Record Set (old)`, `NCP 0x0b Clear Logical Record`, and `NCP 0x0c Release Logical Record` have inline SDK request-layout documentation. The direct old endpoints have been compared against the NDK/Core Protocols PDF request offsets. - `NCP 0x0d Release Logical Record Set` and `NCP 0x0e Clear Logical Record Set` are implemented, but the SDK request contains a `LockFlag` byte that the current code does not read. This parser difference is documented inline but not changed yet. Follow-up: - Decide whether `NCP 0x01` and `NCP 0x02` should be implemented for real old-client compatibility or should return a deliberate `0xfb` unsupported completion with normalized endpoint logging. - Verify `NCP 0x03 Log File (old)` against a real DOS requester or direct test caller; the documented PDF/WebSDK request offsets already match the current parser. - Decide whether the shared `0x04`/`0x6a` parser should keep the current big-endian timeout read for both functions or special-case old `0x04` as documented Lo-Hi after direct requester evidence is available. - Decide whether `0x06`, `0x08`, `0x0d`, and `0x0e` should consume or ignore the documented `LockFlag` byte after direct requester evidence is available. - Decide whether `0x0a` should keep the current big-endian timeout read or special-case the documented old Lo-Hi byte order after direct requester evidence is available. - Continue direct requester or NWTESTS coverage for the file, logical-record, and physical-record synchronization calls that are now wired. #### Legacy utility and message/broadcast calls Current status: - `NCP 0x12 Get Volume Info with Number`, `NCP 0x13 Get Station Number`, `NCP 0x14 Get File Server Date And Time`, and the `NCP 0x15` message group handoff have inline SDK request/reply layout documentation. - The forwarded NetWare 1.x/2.x/3.x-compatible `NCP 0x15` message subfunctions in `src/nwbind.c` have inline SDK request/reply layout documentation for broadcast send/get, enable/disable, and console broadcast calls. - `NCP 0x13 Get Station Number` is documented by the SDK as a three-byte StationNumber reply; MARS-NWE currently returns only the low one-byte connection number. This parser/reply difference is documented inline but not changed yet. Follow-up: - Verify whether the current one-byte `0x13` reply is required by old clients or whether the SDK three-byte StationNumber reply should be implemented. - Verify whether `NCP 0x2222/21/10 Send Broadcast Message` must accept the SDK-documented long connection list and return long completion flags, or whether the current 16-bit connection list plus byte status reply is the requester-compatible format used by the clients MARS-NWE supports. #### Directory Services group 0x2222/22 Current status: - `NCP 0x2222/22` is handled in `src/nwconn.c`, with selected quota-related subfunctions forwarded to `src/nwbind.c` for bindery/ObjectID prehandling. - The group header is documented inline as `SubFuncStrucLen` (Hi-Lo), `SubFunctionCode`, and subfunction payload. - Endpoint numbers in SDK/PDF/WebSDK prose are decimal unless the source explicitly prefixes them with `0x`. The wire `case` byte is listed below whenever decimal and hex notation can be confused. - Already audited and inline-documented default-compatibility calls: - SDK `22/00` / wire `0x00` Set Directory Handle - SDK `22/01` / wire `0x01` Get Directory Path - SDK `22/02` / wire `0x02` Scan Directory Information - SDK `22/03` / wire `0x03` Get Effective Directory Rights - SDK `22/04` / wire `0x04` Modify Maximum Rights Mask - SDK `22/05` / wire `0x05` Get Volume Number - SDK `22/06` / wire `0x06` Get Volume Name - SDK `22/10` / wire `0x0a` Create Directory - SDK `22/11` / wire `0x0b` Delete Directory - SDK `22/13` / wire `0x0d` Add Trustee to Directory - SDK `22/14` / wire `0x0e` Delete Trustee from Directory - SDK `22/15` / wire `0x0f` Rename Directory - SDK `22/18` / wire `0x12` Allocate Permanent Directory Handle - SDK `22/19` / wire `0x13` Allocate Temporary Directory Handle - SDK `22/20` / wire `0x14` Deallocate Directory Handle - SDK `22/21` / wire `0x15` Get Volume Info with Handle - SDK `22/22` / wire `0x16` Allocate Special Temporary Directory Handle - SDK `22/23` / wire `0x17` Extract a Base Handle - SDK `22/24` / wire `0x18` Restore an Extracted Base Handle - SDK `22/25` / wire `0x19` Set Directory Information - SDK `22/26` / wire `0x1a` Get Path Name of a Volume-Directory Number Pair - SDK `22/27` / wire `0x1b` Scan Salvageable Files (old) - SDK `22/28` / wire `0x1c` Recover Salvageable File (old) - SDK `22/29` / wire `0x1d` Purge Salvageable File (old) - SDK `22/30` / wire `0x1e` Scan a Directory - SDK `22/31` / wire `0x1f` Get Directory Entry - SDK `22/32` / wire `0x20` Scan Volume's User Disk Restrictions - SDK `22/33` / wire `0x21` Add User Disk Space Restriction - SDK `22/34` / wire `0x22` Remove User Disk Space Restrictions - SDK `22/37` / wire `0x25` Set Directory Entry Information - SDK `22/38` / wire `0x26` Scan File or Directory for Extended Trustees - SDK `22/39` / wire `0x27` Add Extended Trustee to Directory or File - SDK `22/40` / wire `0x28` Scan Directory Disk Space - SDK `22/41` / wire `0x29` Get Object Disk Usage and Restrictions - SDK `22/42` / wire `0x2a` Get Effective Rights for Directory Entry - SDK `22/43` / wire `0x2b` Remove Extended Trustee from Dir or File - SDK `22/44` / wire `0x2c` Get Volume and Purge Information - SDK `22/45` / wire `0x2d` Get Directory Information - SDK `22/46` / wire `0x2e` Rename Or Move (old) - SDK `22/47` / wire `0x2f` Get Name Space Information - SDK `22/48` / wire `0x30` Get Name Space Directory Entry - Already audited NetWare 4.x planning-bucket calls with existing active MARS-NWE implementations: - SDK `22/50` / wire `0x32` Get Object Effective Rights for Directory Entry - SDK `22/51` / wire `0x33` Get Extended Volume Information These are not part of the default 1.x/2.x/3.x implementation TODO list, but existing compatibility code remains active. - The old SDK PDF table for SDK `22/00` repeats `TargetDirectoryHandle` for the second payload byte, but the remarks describe a source handle; MARS-NWE parses the byte as `SourceDirectoryHandle`. This is documented inline but not changed. - No NetWare 1.x/2.x/3.x SDK/PDF entries were found for direct SDK `22/07`, `22/08`, or `22/09` during this audit. The next documented direct directory calls continue at SDK `22/10` / wire `0x0a`. - WebSDK/PDF recheck found SDK `22/12` / wire `0x0c` Scan Directory for Trustees. Do not confuse this with the already implemented wire `case 0x12` / SDK `22/18` Allocate Permanent Directory Handle. Scan Directory for Trustees has only a disabled inline stub for now. - WebSDK/PDF also documents SDK `22/35` / wire `0x23` Get Directory Disk Space Restriction and SDK `22/36` / wire `0x24` Set Directory Disk Space Restriction as NetWare 3.x-compatible directory quota calls. They are not active cases in this dispatcher yet; disabled inline stubs now sit at their numeric wire slots between SDK `22/34` / wire `0x22` and SDK `22/37` / wire `0x25`. - SDK `22/13` / wire `0x0d` and SDK `22/14` / wire `0x0e` match the SDK/PDF payload layouts. SDK `22/15` / wire `0x0f` matches the payload layout; the old PDF labels this call's `SubFuncStrucLen` as Lo-Hi, but MARS-NWE dispatches the group before using that length word and the surrounding NCP 22 group header is otherwise documented as Hi-Lo. - SDK `22/10` / wire `0x0a` and SDK `22/11` / wire `0x0b` preserve the documented offset of `DirectoryAccessMask`, but the current implementation does not use that field when creating or deleting the directory. - SDK `22/18`, `22/19`, `22/22`, `22/20`, and `22/21` request parsers match the documented NetWare 1.x/2.x/3.x payload offsets. - SDK `22/23` / wire `0x17` and SDK `22/24` / wire `0x18` now have inline request/reply layout documentation. The current parsers match the actual payload fields, but the local NDK/Core Protocols PDF tables for this older NetWare 2.x save/restore pair contain header/length wording that does not line up cleanly with the common `0x2222/22` group header. This is documented inline and no behavior was changed. - SDK `22/25`, `22/26`, `22/27`, and `22/29` match the documented request payload offsets. SDK `22/26` uses the old 16-bit directory-entry-number form; the WebSDK table does not spell out byte order for that word, while MARS-NWE reads it as Hi-Lo. - SDK `22/28` validates the documented old/new filename fields, but the current backend call recovers by directory handle and sequence only and does not pass the old/new names to the salvage backend. - SDK `22/30` / wire `0x1e` matches the documented offsets, but the SDK documents `Sequence` as Lo-Hi while the current parser reads it with `GET_BE32()`. - SDK `22/31` / wire `0x1f` consumes the documented `DirectoryHandle`; legacy source comments expected two extra unknown bytes after it, but the SDK request has no such fields and the helper ignores them. - SDK `22/32` / wire `0x20` reads `VolumeNumber` in the normal NCP 22 payload position, but the WebSDK/PDF table for this call shows `VolumeNumber` one byte later than the common group-header alignment. The code also reads `Sequence` with `GET_BE32()` although the SDK/PDF documents Lo-Hi; treat both as audit items until verified with a direct test caller. - SDK `22/33` and `22/34` are forwarded to `nwbind.c` for quota prehandling; both layers are documented. The shared `nwbind` prehandler reads ObjectID from the documented payload position. SDK `22/33` includes a documented DiskSpaceLimit field, but the current shared prehandler does not consume it before returning the uid/gid/permission tuple. - SDK `22/38`, `22/39`, and `22/41` match the documented request payload offsets. - SDK `22/37` matches the documented payload field order, but the current parser reads Sequence with `GET_BE32()` although the SDK/PDF documents Lo-Hi. - SDK `22/40` matches the documented payload offsets, but the current parser reads Sequence with `GET_BE32()` although the SDK/PDF documents Lo-Hi; it also returns the normal directory scan structure from `nw_scan_a_directory()` rather than the full documented Scan Directory Disk Space reply. - SDK `22/42`, `22/43`, `22/45`, `22/46`, and `22/47` match the NetWare 1.x/2.x/3.x SDK/PDF payload offsets used by the current parser. - SDK `22/44` / wire `0x2c` matches the documented request offset, but the PDF marks `TotalBlocks` as Hi-Lo while the remaining 32-bit counters are Lo-Hi; current code uses `U32_TO_32()` for all counters. - SDK `22/48` / wire `0x30` matches the documented payload offsets; the PDF does not label the `DOSSequence` byte order, and current code reads it with `GET_32()`. Follow-up: - Implement or intentionally reject SDK `22/12` / wire `0x0c` Scan Directory for Trustees. Do not confuse the SDK decimal subfunction number 12 with the already implemented wire `case 0x12` / SDK `22/18` directory-handle call. - Implement or intentionally reject SDK `22/35` / wire `0x23` Get Directory Disk Space Restriction and SDK `22/36` / wire `0x24` Set Directory Disk Space Restriction. Both are NetWare 3.x-compatible, not `MARS_NWE_4` work. - Verify the documented SDK `22/00` source-handle interpretation against an old requester or direct test caller before changing behavior. - Decide whether SDK `22/10` / wire `0x0a` and SDK `22/11` / wire `0x0b` should apply or validate the documented `DirectoryAccessMask` byte, or whether ignoring it is required for old requester compatibility. - Verify SDK `22/23` / wire `0x17` and SDK `22/24` / wire `0x18` against an old requester or direct test caller before changing the conservative connection-local implementation; the SDK/PDF tables for those two NetWare 2.x calls are less internally consistent than the surrounding directory-handle calls. - Verify SDK `22/26` directory-entry-number byte order against an old requester or direct test caller before changing the current Hi-Lo interpretation. - Decide whether SDK `22/28` should pass the documented old/new filename fields to the salvage backend, or whether sequence-only recovery is sufficient for old requester compatibility. - Verify SDK `22/30` Sequence byte order; current code uses `GET_BE32()` although the SDK/WebSDK documents Lo-Hi. - Verify whether SDK `22/31` should continue accepting legacy callers that send the two extra bytes described by the old source comment, even though the SDK request only contains `DirectoryHandle`. - Verify SDK `22/32` VolumeNumber offset and Sequence byte order against a direct test caller; the WebSDK table appears shifted by one byte compared with the normal NCP 22 group header, and current code uses `GET_BE32()` although the SDK/PDF documents Lo-Hi. - Decide whether SDK `22/33` should pass the documented DiskSpaceLimit through the quota prehandling path or whether the current behavior is intentionally handled later in the quota backend. - Verify SDK `22/37` Sequence byte order; current code uses `GET_BE32()` although the SDK/PDF documents Lo-Hi. - Verify SDK `22/40` Sequence byte order and reply shape; current code uses `GET_BE32()` and delegates to the normal directory scan reply rather than the documented Scan Directory Disk Space reply. - Verify SDK `22/44` Volume and Purge Information reply byte order for `TotalBlocks`; the SDK/PDF marks only that field as Hi-Lo, while current code emits all 32-bit counters with `U32_TO_32()`. - Verify SDK `22/48` DOSSequence byte order against an old requester or direct test caller; current code uses `GET_32()` and the PDF table does not spell out the order for that field. - The NetWare 1.x/2.x/3.x-compatible `0x2222/22` endpoint layout pass is covered through the documented SDK `22/48` namespace call, with the newly found SDK `22/12`, `22/35`, and `22/36` gaps tracked as disabled stubs/TODO items. Continue with the next non-4.x/OES-only group after this block. #### File Server Environment group 0x2222/23 Current status: - `NCP 0x2222/23` is handled in `src/nwconn.c` for the locally parsed file-information subfunctions, while other login, bindery, queue, and management subfunctions are forwarded to `src/nwbind.c` or existing queue prehandlers. - The group header is documented inline as `SubFuncStrucLen` (Hi-Lo), `SubFunctionCode`, and subfunction payload. - Endpoint numbers in SDK/PDF/WebSDK prose are decimal unless explicitly prefixed. The local subfunction cases audited so far are: - SDK `23/15` / wire `0x0f` Scan File Information - SDK `23/16` / wire `0x10` Set File Information - SDK `23/15` request payload offsets match the current parser: `LastSearchIndex`, `DirectoryHandle`, `SearchAttributes`, `FileNameLen`, and `FileName`. The reply shape also matches the documented fixed file information block. The SDK/PDF/WebSDK documents `LastSearchIndex` and `NextSearchIndex` as Lo-Hi words, while the current code uses `GET_BE16()` and `U16_TO_BE16()`. - SDK `23/16` request payload field order matches the current parser. The code copies the documented status fields into `NW_FILE_INFO` after its 14-byte DOS-name prefix and then passes the documented directory handle, search attributes, and filename to `nw_set_file_information()`. - Include cross-checks: `NWScanFileInformation()`/`NWIntScanFileInformation()` and `NWSetFileInformation()` in `nwfile.h` refer to this same SDK-level file-information family. Follow-up: - Verify SDK `23/15` search-index byte order against a real old requester or direct test caller before changing the current big-endian parser/reply. - Audit the remaining forwarded `0x2222/23` login, bindery, queue, and management subfunctions in the files that actually handle them instead of treating the `nwconn.c` forwarding points as complete local implementations. ### 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. ### Server logging schema Current status: - Server logging is useful during protocol work, but output is still noisy and not formatted consistently across NCP, namespace/path mapping, AFP, bindery, file, queue, trustee, and salvage code. - During salvage endpoint development, verbose logs are preferred over missing diagnostic information, but the messages should become easier to grep and compare across subsystems. Follow-up: - Normalize new server log lines toward this shape: ```text key=value ... ``` - Use four-character levels so columns do not jump around: - `INFO` - `DBUG` - `WARN` - `ERRR` - Put the level first, then the subsystem/function area, for example `NCP`, `SALVAGE`, `AFP`, `MAP`, `BIND`, `TRUST`, `AUTH`, `CONN`, `FILE`, or `QUEUE`. - Use decimal/protocol-facing endpoint identifiers near the front when they are what the documentation uses, for example `87/16`, `87/17`, and `87/18`. - Keep exact wire values as hex key/value fields later in the same line, for example `fn=0x57 sub=0x10 ns=0x00 seq=0x00000000 vol=0x0000 base=0x00000004 result=0x89ff`. - Mark missing or unimplemented endpoints with a stable `UNKNOWN` event, for example: ```text INFO NCP 87/18 UNKNOWN fn=0x57 sub=0x12 msg="not implemented" INFO NCP 87/255 UNKNOWN fn=0x57 sub=0xff msg="unknown subfunction" INFO NCP 136 UNKNOWN fn=0x88 msg="unknown function" ``` - Prefer existing mars_nwe logging functions/macros. Do not introduce a second logging subsystem just to change the message format. - Convert noisy areas gradually, starting with NCP function/subfunction dispatch and the salvage endpoints. ## 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: - The current AFP compatibility slice is implemented and covered by the smoke tests under `tests/afp/`. Endpoint inventory, WebSDK audit notes, and AFP implementation history live in that directory instead of this project-level TODO file. - AFP `0x13 Get Macintosh Info On Deleted File` is implemented as a salvage/deleted-entry adapter and covered by the AFP smoke suite. It returns FinderInfo, ProDOSInfo, resource fork size, and deleted filename from the shared Salvage snapshot. - ProDOSInfo is persisted through the existing `nwatalk` AFP metadata xattr layer (`org.mars-nwe.afp.prodos-info`) and is captured/restored in Salvage as `prodos_info_hex`; no parallel AFP metadata store was added. - The verified AFP smoke suite covers live FinderInfo/ProDOSInfo xattrs, AFP 35/19 deleted-file metadata, and the readonly Modify-rights negative path. - Keep future AFP deleted-file work on the shared salvage backend; do not expose `.recycle` or `.salvage` through normal AFP/NCP path opens. - Keep AFP metadata restore/lookup paths tied to the existing mars_nwe AFP and nwatalk mechanisms, not a new side database. - Keep the detailed AFP inventory and audit notes in `tests/afp/`. Follow-up: - Continue the final AFP WebSDK audit only where inventory files still mark an endpoint as needing layout verification. AFP 0x13 and ProDOSInfo storage are no longer open TODO items. ## 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.