TODO: keep only active AFP deleted-file follow-up
All checks were successful
Source release / source-package (push) Successful in 48s

This commit is contained in:
OpenAI
2026-05-31 07:15:19 +00:00
committed by Mario Fetka
parent ac79fa9d22
commit 5365f0e37f
2 changed files with 52 additions and 522 deletions

537
TODO.md
View File

@@ -112,28 +112,6 @@ Follow-up:
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
@@ -213,289 +191,24 @@ Follow-up:
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 the WebSDK request shape 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.
- The active 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.
- The only AFP endpoint still tracked here is `0x13 AFP Get Macintosh Info On
Deleted Files`. It depends on a real mars_nwe salvage/deleted-entry backend
and must not be implemented as an AFP-local deleted-file scan.
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.
- Implement or verify the normal NetWare salvage family first:
- `NCP 0x2222 / 87 / 16` - Scan Salvageable Files
- `NCP 0x2222 / 87 / 17` - Recover Salvageable File
- `NCP 0x2222 / 87 / 18` - Purge Salvageable File
- optional legacy `NCP 0x2222 / 22 / 27` - Scan Salvageable File (old)
- After that backend exists, implement AFP `0x13` as an adapter over the
mars_nwe salvage/deleted-entry record.
- Keep the detailed AFP TODO, inventory, and audit notes in `tests/afp/`.
## Deferred / optional protocol work
@@ -505,223 +218,3 @@ Endpoint order:
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 covered 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.
### AFP file fork handle lifecycle
AFP Open File Fork returns a normal mars_nwe/NetWare file handle for the data
fork. File I/O uses the existing NetWare read/write handlers, and handle
lifetime is closed through the normal `NCP 0x42 Close File` path backed by
`nw_close_file()`. There is no separate AFP-private close operation and no
parallel POSIX close path in the AFP frontend.
Runtime status: the full AFP smoke suite is verified with `failures=0` after
adding close-lifecycle probes. The suite opens the AFP data fork, performs a
read or write through the returned NetWare handle, closes that handle through
`NCP 0x42`, and verifies that later I/O on the old handle is rejected. The
same run keeps Resource Fork opens unsupported with the existing completion
code.
### AFP temporary directory handle entry-id resolver coverage
AFP Alloc Temporary Directory Handle now has smoke coverage for both path-backed
and entry-id-only directory requests. The entry-id-only probe resolves
`SYS:PUBLIC` to directory Entry ID `0x00000004`, sends the allocation request
with `path_len=0`, receives a temporary directory handle, and deallocates it
through the normal NetWare handle cleanup path.
Runtime status: the full AFP smoke suite is verified with `failures=0` after
adding the entry-id-only temporary directory handle probe. Directories continue
to use the mars_nwe namespace/basehandle path; file AFP xattr entry IDs are not
used for directory-handle allocation.
### AFP entry-id-relative name lookup coverage
AFP Get Entry ID From Name now has smoke coverage for the WebSDK entry-id-relative
form. The smoke resolves `SYS:PUBLIC` to directory Entry ID `0x00000004`,
sends the leaf name `pmdflts.ini` relative to that directory Entry ID, and
verifies that the reply returns the same file Entry ID as the path-backed and
NetWare-handle entry-id lookups.
Runtime status: the full AFP smoke suite is verified with `failures=0` after
adding the entry-id-relative `AFP Get Entry ID From Name` probe. The server
log shows the request routed through the directory namespace/basehandle
resolver and then back into the normal mars_nwe path resolver; file Entry IDs
are still not used as directory bases.
### AFP timestamp plausibility smoke coverage
AFP Set File Information timestamp handling now has smoke coverage for the
individual WebSDK timestamp bitmap bits. The smoke exercises access, create,
modify, and backup timestamp updates and verifies the returned AFP information
record for sane timestamp fields. Timestamp fields that were not selected by
the request may still be logged internally as `-1`; that value only means
"not supplied by this request" and is valid for non-timestamp operations such
as FinderInfo or attribute updates.
Runtime status: the full AFP smoke suite is verified with `failures=0` after
adding the timestamp plausibility checks. The run confirms the exact Linux
`stat` mtime epoch remains `1700000000` after the AFP modify-time update and
continues to show AFP-only attributes absent when Hidden/System/Archive use the
NetWare attribute path.
### Final AFP endpoint audit before declaring compatibility slice complete
After the current AFP smoke-covered endpoint set is otherwise complete, perform
one final endpoint-by-endpoint audit against the WebSDK archive and the Novell
NWAFP headers. The goal is not to add new semantics, but to verify that every
implemented AFP call number, request layout, reply layout, bitmap, completion
code, and unsupported-operation response still matches the published wire
interfaces.
Checklist for that final audit:
- compare the `nwconn.c` AFP dispatch table with the WebSDK/NWAFP endpoint list;
- verify legacy and AFP 2.0 variants separately;
- re-check Get/Set/Scan File Information record offsets, lengths, and bitmaps;
- re-check Create, Delete, Rename, Open Fork, and Entry-ID resolver request
layouts;
- confirm Resource Fork behaviour remains intentionally unsupported and returns
the documented completion code used by the smoke tests;
- confirm all NetWare-semantic data still routes through mars_nwe paths
(trustees, attributes, timestamps, namespace, directory handles,
create/open/read/write/close/rename/delete), and only AFP-only metadata stays
in `org.mars-nwe.afp.*` xattrs;
- inspect every implemented AFP handler for AFP-local shortcuts and replace any
remaining NetWare-semantic direct POSIX/xattr logic with existing mars_nwe
functions or wrappers before declaring the slice complete;
- keep the result as the final AFP compatibility report in `tests/afp/README.md`.

37
tests/afp/TODO.md Normal file
View File

@@ -0,0 +1,37 @@
# AFP TODO
This file contains only AFP follow-up work that is still open. Smoke results,
endpoint inventory, WebSDK audit notes, and implementation history belong in the
neighboring AFP documentation files, not in the root `TODO.md`.
## Remaining AFP work
### `0x13 AFP Get Macintosh Info On Deleted Files`
Current status:
- Unsupported in the current AFP compatibility slice.
- Documented as salvage/deleted-entry-backend dependent.
- Must not be implemented as an AFP-local deleted-file scan.
Required backend first:
- `NCP 0x2222 / 87 / 16` - Scan Salvageable Files
- `NCP 0x2222 / 87 / 17` - Recover Salvageable File
- `NCP 0x2222 / 87 / 18` - Purge Salvageable File
- Optional legacy `NCP 0x2222 / 22 / 27` - Scan Salvageable File (old)
Future AFP mapping:
1. Resolve the deleted DOS directory entry through the mars_nwe salvage backend.
2. Return FinderInfo from AFP metadata when available, otherwise zeroes.
3. Return ProDOS information as zeroes unless mars_nwe gains a real ProDOS store.
4. Return resource fork size as zero while resource forks remain unsupported.
5. Return the deleted filename from the salvage/deleted-entry record.
References:
- `tests/afp/AFP_DELETED_FILE_INFO.md`
- `tests/afp/AFP_ENDPOINT_INVENTORY.md`
- `tests/afp/AFP_FINAL_AUDIT.md`
- `tests/afp/AFP_WEBSK_AUDIT_FINDINGS.md`