Files
mars-nwe/AI.md
ai 92b0c4a34a
All checks were successful
Source release / source-package (push) Successful in 55s
afp: add deleted file Macintosh info endpoint
2026-06-01 11:07:43 +02:00

9.2 KiB

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:

    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.

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 first implementation returns FinderInfo from the salvage JSON snapshot, ProDOSInfo as zeroes, resource fork size from the JSON snapshot, and the deleted original name.
  • 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, deletes it, verifies AFP 0x13, and purges the tested deleted entry afterwards.
  • 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:

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

    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:

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:

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:

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

Runtime smoke suite:

tests/salvage/salvage_smoke_suite.sh --out /tmp/mars-salvage-report.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.