Files
mars-nwe/AI.md
2026-06-01 21:26:14 +02:00

241 lines
12 KiB
Markdown

# AI working notes for mars-nwe
This file is for future ChatGPT sessions. It records general working rules and
local build/test notes only. It should not be used as the current project
status log; the current patch stack and task context should be pasted into a new
chat separately.
## Start of a new chat
When the user says this is a new chat or asks to continue mars-nwe work, first
read this file before proposing patches or making assumptions. Then ask for, or
use, the current project status that the user pasted into the chat.
## Patch workflow
- Produce patches that apply with exactly:
```sh
git am patchname.patch
```
- Assume the user has already applied and committed accepted earlier patches.
Build every new patch against the current tree the user provides.
- Do not ask the user to apply a long patch chain unless they explicitly say
earlier patches were not committed.
- Keep follow-up patches small and reviewable. Do not mix functional changes,
cleanup, and logging refactors unless the user asks for that.
- If a patch is only documentation or test cleanup, keep it that way.
## Current protocol audit scope
- The current endpoint documentation/audit pass is scoped to NetWare 3.x-compatible NCPs. Do not add NetWare 5.x / MOAB-only endpoints or TODOs unless the user explicitly asks for later-version coverage.
- When a `0x2222` group is forwarded out of `nwconn.c`, document both layers: `nwconn.c` should explain the group handoff/header, and the destination file (for example `nwbind.c`) should document concrete subfunction request/reply layouts.
- For documentation-only endpoint patches, do not change parser offsets, byte order, reply layout, or completion behavior. If the code differs from the SDK layout, document the difference inline and mirror it in `TODO.md` for later testing.
- Keep `TODO.md` endpoint audit notes grouped by logical endpoint family instead of as one long flat list.
- The rejected `0152-docs-note-message-control-subfunction.patch` must not be applied: it documented `0x2222/21/0x0c Connection Message Control`, which is outside the NetWare 3.x MARS-NWE target scope.
## mars-nwe coding style rules
- Prefer existing mars_nwe / NetWare functions over new helper code.
- Before adding a helper, search the tree for an existing equivalent.
- Do not introduce parallel mechanisms for paths, trustees, xattrs, AFP
metadata, copy/write/restore, u16/u32 packing, or logging.
- Use existing integer and wire-format macros such as `GET_16`, `GET_32`,
`U16_TO_16`, `U32_TO_32`, and related mars_nwe helpers instead of open-coded
byte parsing/serialization.
- Use existing namespace/path conversion and basehandle logic instead of parsing
NetWare paths by hand.
- For file restore/copy/write behavior, prefer the existing Novell/mars_nwe file
functions over direct POSIX operations. Use POSIX only where there is no
suitable internal mechanism, and keep it clearly isolated.
- Do not add a new trustee or xattr database. Salvage JSON is a snapshot; real
restore should feed existing mars_nwe trustee/xattr/AFP mechanisms.
## NCP path and hidden repository notes
- Normal NCP path resolution intentionally treats Unix dot path components as
hidden/special. In the classic path resolver (`build_dir_name()` in
`connect.c`), a component beginning with `.` is accepted only for `.`/`..`
semantics; a component such as `.recycle` or `.salvage` returns invalid path
(`0x899c`).
- `nwattrib.c` also marks Unix dot files/directories hidden by default when no
explicit NetWare attributes are stored.
- Therefore `.recycle` and `.salvage` are backend repositories, not user-visible
NCP paths. Tests must not expect `SYS:.recycle/...` or `SYS:.salvage/...` to
open through ordinary NCP file calls.
- Use the official salvage endpoints (`87/16` scan, `87/17` recover, `87/18`
purge, and old `22/27`-`22/29`) to observe or operate on salvage entries.
Verify recovered payload content by reading the restored live file through
NCP, not by opening backend repository paths through NCP.
## Salvage endpoint rules
- `NCP 0x2222 / 87 / 16` is decimal 87/16, implemented as function `0x57`,
subfunction `0x10`.
- `NCP 0x2222 / 87 / 17` is decimal 87/17, function `0x57`, subfunction
`0x11`.
- `NCP 0x2222 / 87 / 18` is decimal 87/18, function `0x57`, subfunction
`0x12`.
- Legacy salvage endpoints are old function `22` decimal / `0x16`:
`22/27` scan, `22/28` recover, and `22/29` purge. They should remain thin
adapters over the same shared salvage backend, not a second implementation.
- Keep `0x57` subfunction dispatch in `handle_func_0x57()` / namespace code,
not as a second subfunction switch in `nwconn.c`.
- Old `0x16` calls need a minimal bridge in namespace code because short
directory handles must be resolved through existing `build_base()` /
`dir_base[]` internals before reaching the shared backend.
- Versioned backend payload names follow Samba `vfs_recycle` literally:
`Copy #1 of NAME`, `Copy #2 of NAME`, ... . Do not localize this string and
do not run it through gettext; the NCP scan reply still reports the original
deleted filename for every version.
- Versioned salvage entries may have different `.recycle`/`.salvage` names but
`87/16` returns the original deleted filename for every version. Do not match
recover/purge by display name alone.
- Scan must treat `.salvage` JSON as a sidecar for the matching `.recycle`
payload. If an external tool such as Samba or an administrator removes the
payload, `87/16` must not return the stale sidecar and should remove the JSON.
The server log should contain a greppable line like
`WARN SALVAGE 87/16 STALE ...` for this cleanup.
- Scan, recover, and purge should share the same scan/sequence/basehandle view
so that a sequence returned by scan identifies the exact sidecar used later.
- The combined salvage smoke suite now covers NCP write/read payloads, 87/18
purge pre-clean, hidden backend repository behavior, stale sidecar cleanup
with a manual payload-removal pause, three version captures, and recovering
the oldest version via sequence 0.
- Append salvage endpoint tests to `tests/salvage/salvage_smoke_suite.sh` rather
than creating unrelated top-level scripts, unless a helper binary is needed
and then started by the suite.
## AFP 0x13 deleted-file info notes
- AFP `0x13 Get Macintosh Info On Deleted File` is NCP `0x2222 / 35 / 19`
(wire subfunction byte `0x13`). The Micro Focus / Novell WebSDK request is
`VolumeNumber` plus `DOSDirectoryNumber`; the reply is FinderInfo[32],
ProDOSInfo[6], ResourceForkSize, FileNameLen, FileName.
- Implement it only as an adapter over the shared mars_nwe salvage/deleted-entry
record. Do not expose or normally open `.recycle` or `.salvage` through AFP
code; those remain hidden backend repositories.
- The implementation returns FinderInfo[32], ProDOSInfo[6], resource fork size,
and deleted original name from the Salvage JSON snapshot. FinderInfo and
ProDOSInfo are captured through the existing nwatalk xattr-backed AFP
metadata store, not through a parallel AFP metadata database.
- The AFP smoke suite has a dedicated `afp_deleted_info_smoke` helper. It
pre-cleans salvage entries in the tested directory through NCP purge, creates
a temporary AFP file, writes FinderInfo and ProDOSInfo, deletes it, verifies
AFP `0x13`, and purges the tested deleted entry afterwards.
- Verified AFP smoke status: the full suite completed with `failures=0` after
AFP 35/19 and ProDOSInfo work. It verifies live FinderInfo and ProDOSInfo
xattrs on `SYS:PUBLIC/pmdflts.ini`, verifies AFP 35/19 returns
`prodos=010203040506` from the deleted-file Salvage snapshot, and leaves
normal AFP-only attributes absent when Hidden/System/Archive map through the
NetWare attribute path.
- Reuse existing AFP/nwatalk metadata mechanisms for FinderInfo, AFP
attributes, entry ids, resource fork state, and related restore/lookup
behavior. Do not add a parallel AFP metadata database.
## Logging rules
Desired future server log format:
```text
<LVL4> <AREA> <DEC-CODE> <EVENT> key=value ...
```
- `LVL4` is exactly four characters: `INFO`, `DBUG`, `WARN`, `ERRR`.
- `AREA` examples: `NCP`, `SALVAGE`, `AFP`, `MAP`, `BIND`, `TRUST`, `AUTH`,
`CONN`, `FILE`, `QUEUE`.
- The front code should be human/protocol decimal where applicable, for example
`87/16`, `87/17`, `87/18`.
- Exact wire values should still be logged later as key/value hex fields, for
example `fn=0x57 sub=0x10 seq=0x00000000 base=0x00000004 result=0x89ff`.
- Unknown or unimplemented endpoints should be easy to grep, 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"
```
- Do not invent a parallel logger casually. Reuse existing mars_nwe logging
functions/macros and normalize message format gradually.
## Build and test notes
Dependencies used during local checks in this conversation:
- `gdbm-1.26.tar.gz`
- `Linux-PAM-1.7.2.tar.xz` for PAM headers; link against system PAM if present
- `ncpfs-master.zip` for the salvage smoke helper client build
- `yyjson` under `third_party/yyjson`
If CMake finds GDBM but a target still cannot see `gdbm.h`, pass include paths
explicitly for local verification, for example:
```sh
CFLAGS="-I/path/to/gdbm/include -I/path/to/Linux-PAM-1.7.2/libpam/include" \
cmake -S . -B build
cmake --build build --target nwconn ncp_salvage_scan_smoke ncp_salvage_recover_smoke
```
Useful quick checks:
```sh
bash -n tests/salvage/salvage_smoke_suite.sh
cc -DLINUX -fsyntax-only -Iinclude -Isrc -Ithird_party/yyjson/src src/nwsalvage.c src/namspace.c
```
When server-side code or smoke helper clients change, rebuild both the server
and the helper targets so the runtime test is not using stale binaries:
```sh
cmake --build build --target nwserv ncpserv
cmake --build build --target \
ncp_delete_smoke \
ncp_read_smoke \
ncp_salvage_scan_smoke \
ncp_salvage_recover_smoke \
ncp_salvage_purge_smoke \
afp_entry_id_smoke \
afp_file_info_smoke \
afp_scan_info_smoke \
afp_set_file_info_smoke \
afp_deleted_info_smoke
```
Runtime smoke suites:
```sh
tests/salvage/salvage_smoke_suite.sh --out /tmp/mars-salvage-report.txt
tests/afp/afp_smoke_suite.sh --out /tmp/mars-afp-smoke.txt
```
The suite streams the report to `--out` while running, so a failure before the
end should still leave useful output. It has a manual stale-payload pause: the
script prints a `sudo rm -f .../.recycle/...` command; remove that payload in a
second shell and press Enter. The next scan should remove the stale sidecar and
`grep` `/var/log/mars_nwe/nw.log` for `WARN SALVAGE 87/16 STALE`.
Normal NCP reads of `.recycle` or `.salvage` are expected to fail with invalid
path. Verify payload data through the visible live file after NCP write or
recover, using `ncp_read_smoke`. Treat the final summary (`failures=0`,
`ncp_warnings=0`) as the important signal.
### AFP ProDOSInfo storage
ProDOSInfo is AFP/NCP per-entry metadata. Store it in the existing nwatalk
AFP metadata layer, not in nwarchive/nwxattr directly and not in a parallel DB.
The xattr key is `user.org.mars-nwe.afp.prodos-info` via the mars_nwe xattr
wrapper name `org.mars-nwe.afp.prodos-info`; it is a raw 6-byte value, analogous
to FinderInfo's 32-byte `org.mars-nwe.afp.finder-info`.
Salvage captures this as `prodos_info_hex` (12 hex characters) beside
`finder_info_hex`. AFP 35/19 Get Macintosh Info On Deleted File returns
FinderInfo[32] followed by ProDOSInfo[6] from the Salvage snapshot. The
verified smoke value is `010203040506` and the Linux xattr dump should show:
```text
user.org.mars-nwe.afp.prodos-info=0x010203040506
```