934 lines
41 KiB
Markdown
934 lines
41 KiB
Markdown
# Linux NCP smoke tests
|
|
|
|
This directory contains optional Linux-side integration tests for endpoints that
|
|
are easier to exercise from a Unix host than from the DOS test utilities.
|
|
|
|
The tests use the ncpfs/libncp client library. They are not built by default
|
|
because they require the host ncpfs development headers/library and a running
|
|
NetWare-compatible server.
|
|
|
|
The AFP endpoints are intentionally conservative. AFP Entry IDs now prefer the
|
|
existing mars_nwe NetWare namespace/basehandle mapping, with cached
|
|
`org.mars-nwe.afp.entry-id` metadata kept only as Apple/AFP compatibility state
|
|
and legacy fallback. This keeps object identity on the existing mars_nwe
|
|
namespace path instead of creating a parallel AFP resolver. The first AFP write
|
|
smoke path is deliberately limited to the FinderInfo bitmap of
|
|
AFP 2.0 Set File Information; CNID allocation, DOS attribute mapping, resource
|
|
fork writes, and data-fork writes remain separate write-safety work. mars_nwe
|
|
source uses Netatalk-style `org.mars-nwe.<domain>.*` xattr names; AFP
|
|
metadata stays under `org.mars-nwe.afp.*` while NetWare-core metadata uses
|
|
`org.mars-nwe.netware.*`. On Linux the local xattr helper stores those through
|
|
the portable `user.` namespace, matching Netatalk's `org.netatalk.*` EA
|
|
abstraction style.
|
|
|
|
Build with:
|
|
|
|
```sh
|
|
cmake -DMARS_NWE_BUILD_LINUX_TESTS=ON ...
|
|
cmake --build . --target afp_entry_id_smoke
|
|
cmake --build . --target afp_file_info_smoke
|
|
cmake --build . --target afp_scan_info_smoke
|
|
cmake --build . --target afp_create_directory_smoke
|
|
cmake --build . --target afp_temp_dir_handle_smoke
|
|
cmake --build . --target afp_set_file_info_smoke
|
|
```
|
|
|
|
|
|
## AFP smoke-suite report helper
|
|
|
|
`afp_smoke_suite.sh` runs the currently verified AFP Linux smoke helpers as one
|
|
collectable report. It is meant for interactive runtime validation after a
|
|
server rebuild: the script prints each helper with the password masked, captures
|
|
new AFP lines appended to the mars_nwe server log while the suite runs, and
|
|
adds `getfattr -e hex` checks for the mars_nwe AFP xattrs on the tested Unix
|
|
file.
|
|
|
|
When `MARS_NWE_BUILD_LINUX_TESTS=ON` is enabled, CMake copies the helper into
|
|
the build `tests/linux` directory through the `afp_smoke_suite` build target.
|
|
This keeps the runtime copy in sync with source changes, and `cmake --build
|
|
<build-dir> --target clean` removes the copied script so stale suite helpers do
|
|
not survive clean rebuilds.
|
|
|
|
Example from the build `tests/linux` directory:
|
|
|
|
```sh
|
|
./afp_smoke_suite.sh \
|
|
-S MARS -U SUPERVISOR -P secret \
|
|
--path SYS:PUBLIC/pmdflts.ini \
|
|
--unix-path /var/mars_nwe/SYS/public/pmdflts.ini \
|
|
--log /var/log/mars_nwe/nw.log \
|
|
--out /tmp/mars-afp-smoke.txt
|
|
```
|
|
|
|
The report includes AFP Entry ID, Entry ID From NetWare Handle, Get File
|
|
Information, Scan File Information, Alloc Temporary Directory Handle, AFP Create
|
|
Directory for both legacy (`0x01`) and AFP 2.0 (`0x0d`), Open File
|
|
Fork, FinderInfo Set File Information for both AFP 2.0 (`0x10`) and the legacy AFP
|
|
Set File Information (`0x09`), AFP 2.0 Hidden/System/Archive Set/Clear File
|
|
Information, legacy AFP `0x09` Hidden Set/Clear coverage, and the Linux xattr
|
|
checks for:
|
|
|
|
```text
|
|
user.org.mars-nwe.afp.finder-info
|
|
user.org.mars-nwe.afp.attributes
|
|
user.org.mars-nwe.afp.entry-id
|
|
```
|
|
|
|
|
|
The suite now also exercises the additional metadata-only AFP attribute bits that
|
|
`afp_set_file_info_smoke` supports: Hidden (`0x0200`), System (`0x0400`), and Archive (`0x2000`).
|
|
It additionally runs the legacy AFP `0x09` path for FinderInfo and the Invisible
|
|
attribute so both Set File Information entry points cover the metadata write
|
|
path. It clears each attribute bit again before the final xattr dump so repeated
|
|
runs leave the attribute payload in the clean `0x01000000` state unless a
|
|
previous command fails.
|
|
|
|
Use `--no-log` when the log file is unavailable or when the server log is being
|
|
collected separately. Use `--stop-on-failure` for strict bisect-style runs; by
|
|
default the script keeps going so one failing endpoint does not hide later AFP
|
|
output from the report.
|
|
|
|
The suite can optionally exercise the Modify-rights negative path with a second
|
|
user. For a no-password test user such as `NOPASSUSER`, run from the build
|
|
`tests/linux` directory:
|
|
|
|
```sh
|
|
./afp_smoke_suite.sh \
|
|
-S MARS -U SUPERVISOR -P secret \
|
|
--path SYS:PUBLIC/pmdflts.ini \
|
|
--unix-path /var/mars_nwe/SYS/public/pmdflts.ini \
|
|
--readonly-user NOPASSUSER --readonly-no-password \
|
|
--prepare-readonly-rights \
|
|
--out /tmp/mars-afp-smoke.txt
|
|
```
|
|
|
|
`--prepare-readonly-rights` uses the standard ncpfs trustee utilities instead
|
|
of ad-hoc test NCPs: it calls `nwrevoke` to remove any explicit assignment for
|
|
the readonly user on the smoke file, then `nwgrant -r '[RF]'` to grant read and
|
|
file-scan rights without Modify. After the negative probes it runs `nwrevoke`
|
|
again so the file returns to inherited rights. Use this only on smoke files or
|
|
paths where removing an explicit trustee assignment for the readonly test user
|
|
is acceptable.
|
|
|
|
AFP metadata writes and NetWare Modify rights:
|
|
|
|
FinderInfo and AFP-only attribute metadata are stored in `org.mars-nwe.afp.*`
|
|
xattrs, but those writes are still file metadata changes. The Set File
|
|
Information handler now resolves the target through the normal mars_nwe path and
|
|
checks the existing NetWare Modify trustee policy before updating FinderInfo or
|
|
AFP-only Hidden/System metadata. Archive uses the existing NetWare attribute
|
|
path, and Modify timestamp uses `nw_utime_node()`, so the smoke suite should
|
|
continue to pass for SUPERVISOR while non-supervisor negative coverage can later
|
|
exercise the same policy gate.
|
|
|
|
A verified rights-negative smoke run with `--readonly-user NOPASSUSER`,
|
|
`--readonly-no-password`, and `--prepare-readonly-rights` completed with
|
|
`failures=0`. The setup used `nwgrant -r '[RF]'` for the no-password test
|
|
user so the file remained readable and searchable but lacked Modify rights.
|
|
The suite then verified that AFP Set File Information rejects FinderInfo,
|
|
Hidden, and System metadata writes with completion `0x8c` while the
|
|
SUPERVISOR positive path still succeeds:
|
|
|
|
```text
|
|
AFP metadata Modify rights rejected: FinderInfo
|
|
AFP Set File Information returned expected completion 0x8c: subfunction=0x10 path=SYS:PUBLIC/pmdflts.ini bitmap=0x0020
|
|
AFP metadata Modify rights rejected: Invisible
|
|
AFP Set File Information returned expected completion 0x8c: subfunction=0x10 path=SYS:PUBLIC/pmdflts.ini bitmap=0x0001
|
|
AFP metadata Modify rights rejected: System
|
|
AFP Set File Information returned expected completion 0x8c: subfunction=0x10 path=SYS:PUBLIC/pmdflts.ini bitmap=0x0001
|
|
```
|
|
|
|
The server log for the same run showed the common policy gate for all three
|
|
probes:
|
|
|
|
```text
|
|
AFP 2.0 Set File Information rejected: no Modify rights for AFP metadata path='SYS:PUBLIC/pmdflts.ini'
|
|
```
|
|
|
|
The final `nwrevoke` cleanup returned successfully, and the final xattr/stat
|
|
checks remained intact. An initial pre-cleanup `nwrevoke` may report that no
|
|
explicit assignment existed yet; that is harmless as long as `nwgrant` and the
|
|
final cleanup both succeed.
|
|
|
|
A verified suite run after the FinderInfo payload-alignment fix completed with
|
|
`failures=0` for `SYS:PUBLIC/pmdflts.ini`. The report covered Entry ID by path,
|
|
Entry ID from NetWare handle, Get File Information, Scan File Information,
|
|
Alloc Temporary Directory Handle, Open File Fork, FinderInfo Set File
|
|
Information, and Finder Hidden set/clear. The relevant Linux xattr checks
|
|
from that run were:
|
|
|
|
```text
|
|
user.org.mars-nwe.afp.finder-info=0x544558544d415253000000000000000000000000000000000000000000000000
|
|
user.org.mars-nwe.afp.attributes=0x01000000
|
|
user.org.mars-nwe.afp.entry-id=0x0100000033f9a1ed
|
|
```
|
|
|
|
The FinderInfo value starts with `TEXTMARS` without a leading padding byte, so
|
|
the smoke helper and server now agree on the WebSDK/NWAFP Set File Information
|
|
payload alignment. The server log excerpt for the same run showed all AFP
|
|
operations returning successfully, including `mask=0x0020` for FinderInfo and
|
|
`mask=0x0001` for the Hidden/System/Archive attribute probes.
|
|
|
|
|
|
A later full-suite run after the smoke-suite copy/sync fix also completed with
|
|
`failures=0` from the build-tree script and confirmed that the legacy AFP Set
|
|
File Information endpoint (`0x09`) is exercised in the same report as AFP 2.0
|
|
`0x10`. The run covered legacy FinderInfo, legacy Hidden set/clear, AFP 2.0
|
|
System set/clear, and AFP 2.0 Archive set/clear while leaving the final AFP
|
|
metadata attributes xattr clear:
|
|
|
|
```text
|
|
AFP Set File Info subfunction=0x09 path=SYS:PUBLIC/pmdflts.ini bitmap=0x0020 attrs=0x0000 finder_type=TEXT finder_creator=MARS entry_id=0x1ad06d3e verified
|
|
AFP Set File Info subfunction=0x09 path=SYS:PUBLIC/pmdflts.ini bitmap=0x0001 attrs=0x0001 finder_type=TEXT finder_creator=MARS entry_id=0x1ad06d3e verified
|
|
AFP Set File Info subfunction=0x09 path=SYS:PUBLIC/pmdflts.ini bitmap=0x0001 attrs=0x0000 finder_type=TEXT finder_creator=MARS entry_id=0x1ad06d3e verified
|
|
AFP Set File Info subfunction=0x10 path=SYS:PUBLIC/pmdflts.ini bitmap=0x0001 attrs=0x0004 finder_type=TEXT finder_creator=MARS entry_id=0x1ad06d3e verified
|
|
AFP Set File Info subfunction=0x10 path=SYS:PUBLIC/pmdflts.ini bitmap=0x0001 attrs=0x0000 finder_type=TEXT finder_creator=MARS entry_id=0x1ad06d3e verified
|
|
AFP Set File Info subfunction=0x10 path=SYS:PUBLIC/pmdflts.ini bitmap=0x0001 attrs=0x2000 finder_type=TEXT finder_creator=MARS entry_id=0x1ad06d3e verified
|
|
AFP Set File Info subfunction=0x10 path=SYS:PUBLIC/pmdflts.ini bitmap=0x0001 attrs=0x0000 finder_type=TEXT finder_creator=MARS entry_id=0x1ad06d3e verified
|
|
user.org.mars-nwe.afp.finder-info=0x544558544d415253000000000000000000000000000000000000000000000000
|
|
user.org.mars-nwe.afp.attributes=0x01000000
|
|
user.org.mars-nwe.afp.entry-id=0x010000001ad06d3e
|
|
```
|
|
|
|
|
|
## AFP Create Directory smoke test
|
|
|
|
`afp_create_directory_smoke` sends the WebSDK/nwafp.h AFP Create Directory
|
|
requests through libncp:
|
|
|
|
```text
|
|
NCP 0x2222/35/01 AFP Create Directory
|
|
NCP 0x2222/35/0d AFP 2.0 Create Directory
|
|
```
|
|
|
|
The helper derives the parent Entry ID with the existing AFP Entry ID From Path
|
|
Name endpoint, sends only the new leaf name to Create Directory, and verifies
|
|
the returned directory ID by looking the created path up again. This exercises
|
|
the server-side path through the existing mars_nwe namespace/basehandle mapping
|
|
and `nw_mk_rd_dir()` rather than an AFP-only directory resolver.
|
|
|
|
Example:
|
|
|
|
```sh
|
|
./tests/linux/afp_create_directory_smoke -S MARS -U SUPERVISOR -P secret SYS:PUBLIC/afpdirts
|
|
./tests/linux/afp_create_directory_smoke --afp20 -S MARS -U SUPERVISOR -P secret SYS:PUBLIC/afpdirts2
|
|
```
|
|
|
|
The full smoke suite creates temporary directories under the tested parent and
|
|
removes them through the local Unix path after each positive probe. Use
|
|
`--create-dir-name NAME` to override the default temporary leaf name.
|
|
|
|
## AFP Entry ID smoke test
|
|
|
|
`afp_entry_id_smoke` sends the WebSDK-documented NetWare AFP request:
|
|
|
|
```text
|
|
NCP 0x2222/35/12 AFP Get Entry ID From Path Name
|
|
```
|
|
|
|
It uses libncp's `NWRequestSimple()` path, so it goes through the same client
|
|
transport stack as other Linux ncpfs utilities.
|
|
|
|
Example:
|
|
|
|
```sh
|
|
./tests/linux/afp_entry_id_smoke -S MARS -U SUPERVISOR -P secret SYS:PUBLIC
|
|
```
|
|
|
|
The test accepts NetWare-style `VOL:PATH` arguments. By default it sends the
|
|
supplied `SYS:`-style path directly with directory handle 0, matching the
|
|
verified mars_nwe smoke-test path. `--alloc-handle` is available only for
|
|
follow-up debugging of the separate directory-handle allocation path, and
|
|
`--dir-handle N` expects a handle that is valid in the current connection.
|
|
|
|
Useful smoke cases for a standard MARS-NWE `SYS` volume are:
|
|
|
|
```sh
|
|
./tests/linux/afp_entry_id_smoke -S MARS -U SUPERVISOR -P secret SYS:
|
|
./tests/linux/afp_entry_id_smoke -S MARS -U SUPERVISOR -P secret SYS:PUBLIC
|
|
./tests/linux/afp_entry_id_smoke -S MARS -U SUPERVISOR -P secret SYS:SYSTEM
|
|
./tests/linux/afp_entry_id_smoke -S MARS -U SUPERVISOR -P secret SYS:BURST
|
|
```
|
|
|
|
A successful reply prints the request path, directory handle, and returned
|
|
32-bit AFP Entry ID. Current AFP Entry IDs are normally derived from the
|
|
existing NetWare namespace/basehandle mapping. A full-suite run after that
|
|
change returned `entry_id=0x00000004` for `SYS:PUBLIC/pmdflts.ini`.
|
|
|
|
If the server was built without the optional Netatalk/libatalk backend, the
|
|
endpoint is expected to return invalid namespace. To treat that as a successful
|
|
negative smoke test, use:
|
|
|
|
```sh
|
|
./tests/linux/afp_entry_id_smoke --allow-invalid-namespace -S MARS -U SUPERVISOR -P secret SYS:PUBLIC
|
|
```
|
|
|
|
For path-resolution negative tests, use `--allow-invalid-path` to accept the
|
|
expected `0x9c` Invalid Path completion.
|
|
|
|
|
|
### AFP Get Entry ID From Name
|
|
|
|
`afp_entry_id_smoke` can also exercise the WebSDK-documented NetWare AFP
|
|
request:
|
|
|
|
```text
|
|
NCP 0x2222/35/04 AFP Get Entry ID From Name
|
|
```
|
|
|
|
Use `--from-name` to select this subfunction. The current mars_nwe
|
|
implementation supports the same verified path-backed smoke mode as
|
|
`AFP Get Entry ID From Path Name`: pass a raw `SYS:`-style path with directory
|
|
handle 0 and base Entry ID 0.
|
|
|
|
Useful smoke cases for a standard MARS-NWE `SYS` volume are:
|
|
|
|
```sh
|
|
./tests/linux/afp_entry_id_smoke --from-name -S MARS -U SUPERVISOR -P secret SYS:
|
|
./tests/linux/afp_entry_id_smoke --from-name -S MARS -U SUPERVISOR -P secret SYS:PUBLIC
|
|
./tests/linux/afp_entry_id_smoke --from-name -S MARS -U SUPERVISOR -P secret SYS:SYSTEM
|
|
./tests/linux/afp_entry_id_smoke --from-name -S MARS -U SUPERVISOR -P secret SYS:BURST
|
|
```
|
|
|
|
A successful reply prints the same 32-bit AFP Entry ID format as the path-name
|
|
probe and uses the same NetWare namespace/basehandle identity source for
|
|
path-backed requests.
|
|
|
|
### AFP Get Entry ID From NetWare Handle
|
|
|
|
`afp_entry_id_smoke` can also exercise the WebSDK-documented NetWare AFP
|
|
request:
|
|
|
|
```text
|
|
NCP 0x2222/35/06 AFP Get Entry ID From NetWare Handle
|
|
```
|
|
|
|
Use `--from-handle` to select this subfunction. The smoke test opens the
|
|
requested file through libncp in the same connection, passes the returned
|
|
6-byte NetWare file handle to the AFP request, and closes the file after the
|
|
AFP reply. This is important because NetWare file handles are connection-local:
|
|
`--dir-handle N` and file-handle values copied from server logs or unrelated
|
|
helper processes are not stable inputs for this request.
|
|
|
|
Useful smoke cases for a standard MARS-NWE `SYS:PUBLIC` directory are:
|
|
|
|
```sh
|
|
./tests/linux/afp_entry_id_smoke --from-handle -S MARS -U SUPERVISOR -P secret SYS:PUBLIC/pmdflts.ini
|
|
./tests/linux/afp_entry_id_smoke --from-handle -S MARS -U SUPERVISOR -P secret SYS:PUBLIC/ohlogscr.bat
|
|
```
|
|
|
|
Successful replies print the resolved volume number, 32-bit AFP Entry ID, and
|
|
fork indicator. The current implementation reports the data fork (`fork=0`)
|
|
and derives the Entry ID from the same mars_nwe namespace/basehandle mapping as
|
|
path-backed lookups:
|
|
|
|
```text
|
|
AFP Entry ID From NetWare Handle path=SYS:PUBLIC/pmdflts.ini volume=0 entry_id=0x00000004 (4) fork=0
|
|
AFP Get Entry ID From NetWare Handle: handle=1 volume=0 unix='/var/mars_nwe/SYS/public/pmdflts.ini' entry=0x00000004
|
|
```
|
|
|
|
Persistent Apple CNID/AppleDouble/libatalk-backed identity, parent Entry ID
|
|
derivation, and AFP resource-fork handle semantics remain future Mac-namespace
|
|
work; the current smoke coverage verifies the conservative read-only data-fork
|
|
mapping through the existing NetWare namespace identity path.
|
|
|
|
## AFP Alloc Temporary Directory Handle smoke test
|
|
|
|
`afp_temp_dir_handle_smoke` sends the WebSDK-documented NetWare AFP request:
|
|
|
|
```text
|
|
NCP 0x2222/35/11 AFP Alloc Temporary Directory Handle
|
|
```
|
|
|
|
The request layout is the AFP volume number, base AFP Entry ID, path length,
|
|
and AFP-style path. The current mars_nwe implementation supports the same
|
|
conservative path-backed subset as the Entry ID and File Information probes:
|
|
pass a raw `VOL:`-style path such as `SYS:` or `HOME:` and keep the
|
|
base Entry ID at zero. The compatibility server resolves the effective
|
|
NetWare volume from that path prefix instead of assuming volume 0; the request
|
|
volume byte is retained for WebSDK/header shape and for later Entry-ID-relative
|
|
lookup work. Pure Entry-ID-relative allocation is still rejected with Invalid
|
|
Path until persistent CNID/base-ID lookup exists.
|
|
|
|
Useful smoke cases for a standard MARS-NWE `SYS` volume are:
|
|
|
|
```sh
|
|
./tests/linux/afp_temp_dir_handle_smoke -S MARS -U SUPERVISOR -P secret SYS:
|
|
./tests/linux/afp_temp_dir_handle_smoke -S MARS -U SUPERVISOR -P secret SYS:PUBLIC
|
|
./tests/linux/afp_temp_dir_handle_smoke -S MARS -U SUPERVISOR -P secret SYS:SYSTEM
|
|
./tests/linux/afp_temp_dir_handle_smoke -S MARS -U SUPERVISOR -P secret SYS:BURST
|
|
```
|
|
|
|
On installations with another exported volume, the same helper can be run
|
|
against that raw prefix, for example `HOME:`. The server log should then show
|
|
the resolved volume number for `HOME:` rather than hard-coded `vol=0`.
|
|
|
|
A successful reply prints the allocated temporary NetWare directory handle and
|
|
the effective-rights mask returned by the server. The smoke helper immediately
|
|
deallocates the handle with the normal NetWare Deallocate Directory Handle call
|
|
before closing the connection, so the handle value is only useful inside that
|
|
client connection and must not be copied into later tests or server logs.
|
|
|
|
Runtime-verified output and server diagnostic shape:
|
|
|
|
```text
|
|
AFP Alloc Temporary Dir Handle path=SYS: dir_handle=2 rights=0xff
|
|
AFP Alloc Temporary Dir Handle path=SYS:PUBLIC dir_handle=2 rights=0xff
|
|
AFP Alloc Temporary Dir Handle path=SYS:SYSTEM dir_handle=2 rights=0xff
|
|
AFP Alloc Temporary Dir Handle path=SYS:BURST dir_handle=2 rights=0xff
|
|
AFP Alloc Temporary Dir Handle: vol=0 request_vol=0 entry=0x00000000 path='SYS:' dir_handle=2 rights=0x1ff
|
|
AFP Alloc Temporary Dir Handle: vol=0 request_vol=0 entry=0x00000000 path='SYS:PUBLIC' dir_handle=2 rights=0x1ff
|
|
AFP Alloc Temporary Dir Handle: vol=0 request_vol=0 entry=0x00000000 path='SYS:SYSTEM' dir_handle=2 rights=0x1ff
|
|
AFP Alloc Temporary Dir Handle: vol=0 request_vol=0 entry=0x00000000 path='SYS:BURST' dir_handle=2 rights=0x1ff
|
|
```
|
|
|
|
The AFP reply carries the one-byte access-rights field consumed by the smoke
|
|
helper, so the client prints `0xff`. The server diagnostic logs the internal
|
|
NetWare effective-rights mask before that AFP reply narrowing, so a fully
|
|
privileged directory can appear as `0x1ff` in `mars_nwe.log`.
|
|
|
|
If the server was built without the optional Netatalk/libatalk backend, use
|
|
`--allow-invalid-namespace` for the expected negative test. Use
|
|
`--allow-invalid-path` for path-resolution negative tests.
|
|
|
|
|
|
## AFP Open File Fork smoke test
|
|
|
|
`afp_open_file_fork_smoke` sends the WebSDK-documented NetWare AFP open fork
|
|
request:
|
|
|
|
```text
|
|
NCP 0x2222/35/08 AFP Open File Fork
|
|
```
|
|
|
|
The first mars_nwe implementation is deliberately conservative. It supports
|
|
raw `VOL:`-style path requests such as `SYS:` or `HOME:` with base Entry ID
|
|
zero, opens only the AFP data fork, and only for read access. For path-backed
|
|
requests, mars_nwe resolves the effective NetWare volume from the raw path
|
|
prefix instead of assuming volume 0. On success the server returns the
|
|
normal six-byte NetWare file handle shape used by AFP handle APIs plus the
|
|
current data-fork length. The smoke helper immediately closes the returned
|
|
NetWare file handle in the same connection.
|
|
|
|
Useful smoke cases for a standard MARS-NWE `SYS` volume are:
|
|
|
|
```sh
|
|
./tests/linux/afp_open_file_fork_smoke -S MARS -U SUPERVISOR -P secret SYS:PUBLIC/pmdflts.ini
|
|
./tests/linux/afp_open_file_fork_smoke -S MARS -U SUPERVISOR -P secret SYS:PUBLIC/ohlogscr.bat
|
|
```
|
|
|
|
A file on another exported volume should be tested with its raw volume prefix
|
|
(for example `HOME:...`). The matching server log should report that resolved
|
|
volume number, while still showing the request volume byte separately.
|
|
|
|
A successful reply prints the returned NetWare handle, the requested fork, the
|
|
read access mode, and the data-fork length. A verified runtime smoke run
|
|
against the standard DOS utility files produced:
|
|
|
|
```text
|
|
AFP Open File Fork path=SYS:PUBLIC/pmdflts.ini handle=1 fork=0 access=0x01 fork_len=8161
|
|
AFP Open File Fork path=SYS:PUBLIC/ohlogscr.bat handle=1 fork=0 access=0x01 fork_len=1296
|
|
```
|
|
|
|
The matching server log records the path-backed open and the same data-fork
|
|
lengths:
|
|
|
|
```text
|
|
AFP Open File Fork: vol=0 request_vol=0 entry=0x00000000 fork=0 access=0x01 path='SYS:PUBLIC/pmdflts.ini' handle=1 fork_len=8161
|
|
AFP Open File Fork: vol=0 request_vol=0 entry=0x00000000 fork=0 access=0x01 path='SYS:PUBLIC/ohlogscr.bat' handle=1 fork_len=1296
|
|
```
|
|
|
|
The exact handle number is connection-local and must not be reused across
|
|
processes. The exact `fork_len` depends on the backing file contents.
|
|
Resource-fork opens (`--fork 1`), write access (`--access 2`), and
|
|
Entry-ID-only open remain unsupported until persistent CNID/base-ID lookup,
|
|
AppleDouble/resource-fork, and AFP write-open semantics are available. The
|
|
smoke helper can assert those conservative rejections explicitly:
|
|
|
|
```sh
|
|
./tests/linux/afp_open_file_fork_smoke --expect-completion 0x84 --access 0x02 -S MARS -U SUPERVISOR -P secret SYS:PUBLIC/pmdflts.ini
|
|
./tests/linux/afp_open_file_fork_smoke --expect-completion 0x9c --fork 1 -S MARS -U SUPERVISOR -P secret SYS:PUBLIC/pmdflts.ini
|
|
```
|
|
|
|
A rejected write-open probe should print:
|
|
|
|
```text
|
|
AFP Open File Fork returned expected completion 0x84: path=SYS:PUBLIC/pmdflts.ini fork=0 access=0x02
|
|
```
|
|
|
|
A rejected resource-fork probe should print:
|
|
|
|
```text
|
|
AFP Open File Fork returned expected completion 0x9c: path=SYS:PUBLIC/pmdflts.ini fork=1 access=0x01
|
|
```
|
|
|
|
If the server was built without the optional Netatalk/libatalk backend, use
|
|
`--allow-invalid-namespace` for the expected negative test. Use
|
|
`--allow-invalid-path` for path-resolution or Entry-ID-only negative tests.
|
|
|
|
## AFP File Information smoke test
|
|
|
|
`afp_file_info_smoke` sends the WebSDK-documented NetWare AFP file
|
|
information requests:
|
|
|
|
```text
|
|
NCP 0x2222/35/05 AFP Get File Information
|
|
NCP 0x2222/35/15 AFP 2.0 Get File Information
|
|
```
|
|
|
|
It uses the same libncp `NWRequestSimple()` transport path as the Entry ID
|
|
smoke test and sends raw `SYS:`-style path requests with directory handle 0.
|
|
The server replies with the read-only AFP file information record currently
|
|
implemented by mars_nwe: Entry ID, Parent ID, attributes, data/resource fork
|
|
lengths, offspring count, fixed long/short names, and access rights.
|
|
|
|
|
|
### AFP Get/Scan AccessPrivileges smoke
|
|
|
|
AFP Get File Information and AFP Scan File Information now derive the
|
|
`AccessPrivileges` word from mars_nwe trustee/effective-rights state instead
|
|
of returning the old static compatibility masks. The WebSDK AccessPrivileges
|
|
bits exposed by the smoke helpers are:
|
|
|
|
```text
|
|
0x0100 Read
|
|
0x0200 Write
|
|
0x0400 Open
|
|
0x0800 Create
|
|
0x1000 Delete
|
|
0x2000 Parental
|
|
0x4000 Search
|
|
0x8000 Modify File Status Flags
|
|
```
|
|
|
|
The AFP smoke suite exercises this with the same readonly trustee setup used by
|
|
the metadata negative tests. With `--readonly-user NOPASSUSER`,
|
|
`--readonly-no-password`, and `--prepare-readonly-rights`, the suite grants
|
|
`[RF]` on `SYS:PUBLIC/pmdflts.ini` and verifies that Get File Information
|
|
reports readable/openable rights while write and modify-status rights are not
|
|
set:
|
|
|
|
```sh
|
|
./afp_file_info_smoke \
|
|
--expect-rights-set 0x0100 \
|
|
--expect-rights-clear 0x9200 \
|
|
-S MARS -U NOPASSUSER -n \
|
|
SYS:PUBLIC/pmdflts.ini
|
|
```
|
|
|
|
Runtime status: the trustee-derived AccessPrivileges smoke run is verified
|
|
with `failures=0`. The report showed the Supervisor Get/Scan replies returning
|
|
`rights=0x9f00`, while the readonly `NOPASSUSER` probe returned `rights=0x0500`
|
|
under the temporary `[RF]` trustee assignment and satisfied the set/clear mask
|
|
checks.
|
|
|
|
Useful smoke cases for a standard MARS-NWE `SYS` volume are:
|
|
|
|
```sh
|
|
./tests/linux/afp_file_info_smoke -S MARS -U SUPERVISOR -P secret SYS:
|
|
./tests/linux/afp_file_info_smoke -S MARS -U SUPERVISOR -P secret SYS:PUBLIC
|
|
./tests/linux/afp_file_info_smoke -S MARS -U SUPERVISOR -P secret SYS:SYSTEM
|
|
./tests/linux/afp_file_info_smoke -S MARS -U SUPERVISOR -P secret SYS:BURST
|
|
|
|
# AFP 2.0 variant using the same path-backed read-only reply
|
|
./tests/linux/afp_file_info_smoke --afp20 -S MARS -U SUPERVISOR -P secret SYS:
|
|
./tests/linux/afp_file_info_smoke --afp20 -S MARS -U SUPERVISOR -P secret SYS:PUBLIC
|
|
./tests/linux/afp_file_info_smoke --afp20 -S MARS -U SUPERVISOR -P secret SYS:SYSTEM
|
|
./tests/linux/afp_file_info_smoke --afp20 -S MARS -U SUPERVISOR -P secret SYS:BURST
|
|
```
|
|
|
|
The AFP 2.0 mode is selected with `--afp20`. It has been verified against
|
|
the same `SYS:`, `SYS:PUBLIC`, `SYS:SYSTEM`, and `SYS:BURST` paths and
|
|
currently exercises the same path-backed read-only reply as the older call.
|
|
The current implementation fills fields from the existing mars_nwe sources of
|
|
truth where possible: NetWare attributes, namespace/basehandle Entry IDs,
|
|
trustee-derived AccessPrivileges, Unix file sizes and timestamps, and optional
|
|
AFP/libatalk metadata such as FinderInfo. Parent ID, persistent Apple
|
|
CNID/AppleDouble IDs, and fuller resource-fork semantics remain future
|
|
Mac-namespace work.
|
|
|
|
If the server was built without the optional Netatalk/libatalk backend, use
|
|
`--allow-invalid-namespace` for the expected negative test. Use
|
|
`--allow-invalid-path` for path-resolution negative tests.
|
|
|
|
## AFP Scan File Information smoke test
|
|
|
|
`afp_scan_info_smoke` sends the WebSDK-documented NetWare AFP scan requests:
|
|
|
|
```text
|
|
NCP 0x2222/35/10 AFP Scan File Information
|
|
NCP 0x2222/35/17 AFP 2.0 Scan File Information
|
|
```
|
|
|
|
The helper defaults to the AFP 2.0 subfunction (`0x11`) and uses `--afp10`
|
|
to exercise the older `0x0a` endpoint. Both variants include the documented
|
|
DesiredResponseCount word; mars_nwe currently returns one path-backed read-only
|
|
entry per request, using the same AFP file information record as
|
|
`afp_file_info_smoke`. The test sends raw `SYS:`-style path requests with
|
|
directory handle 0 and uses the returned `next_last_seen` AFP Entry ID as the
|
|
continuation token for the next call.
|
|
|
|
Useful smoke sequence for a standard MARS-NWE `SYS:PUBLIC` directory:
|
|
|
|
```sh
|
|
./tests/linux/afp_scan_info_smoke -S MARS -U SUPERVISOR -P secret SYS:PUBLIC
|
|
./tests/linux/afp_scan_info_smoke --afp10 -S MARS -U SUPERVISOR -P secret SYS:PUBLIC
|
|
./tests/linux/afp_scan_info_smoke -S MARS -U SUPERVISOR -P secret --last-seen 0x260437f6 SYS:PUBLIC
|
|
./tests/linux/afp_scan_info_smoke -S MARS -U SUPERVISOR -P secret --last-seen 0x6686342b SYS:PUBLIC
|
|
```
|
|
|
|
Verified runtime output from the sample `SYS:PUBLIC` tree after Entry IDs were
|
|
moved onto the existing mars_nwe namespace/basehandle path:
|
|
|
|
```text
|
|
AFP Scan File Info subfunction=0x11 path=SYS:PUBLIC last_seen=0x00000000 desired=1 next_last_seen=0x00000004 entry_id=0x00000004 parent_id=0x00000000 attrs=0x2000 data_len=44424 resource_len=0 offspring=0 long_name=debug.exe short_name=debug.exe rights=0x9f00
|
|
```
|
|
|
|
The AFP entry-id xattr remains a compatibility/cache location rather than the
|
|
source of truth. A final xattr dump from the same run showed the cached value
|
|
matching the namespace-derived ID:
|
|
|
|
```text
|
|
user.org.mars-nwe.afp.entry-id=0x0100000000000004
|
|
```
|
|
|
|
If that cache write is rejected, the server logs it and continues because the
|
|
namespace/basehandle mapping can still resolve the object.
|
|
|
|
The scan continuation order is deliberately documented as server directory
|
|
iteration order, not numeric Entry-ID order. `last_seen` identifies the Entry
|
|
ID that was returned by the previous scan call so mars_nwe can skip entries
|
|
until that object is seen and then return the next directory entry. Therefore
|
|
the next returned Entry ID is not guaranteed to be numerically greater than the
|
|
`last_seen` value; in the verified run, `last_seen=0x6686342b` returns
|
|
`pmail.bat` with `entry_id=0x2d12d99c`. The older `0x0a` path intentionally
|
|
shares the same conservative scan implementation so older AFP callers can probe
|
|
the same read-only directory listing semantics before fuller multi-response and
|
|
CNID-backed scans are implemented.
|
|
|
|
If the server was built without the optional Netatalk/libatalk backend, use
|
|
`--allow-invalid-namespace` for the expected negative test. Use
|
|
`--allow-invalid-path` for path-resolution negative tests, and `--allow-empty`
|
|
when a scan continuation is expected to reach the end of the directory.
|
|
|
|
|
|
## AFP Set File Information metadata smoke test
|
|
|
|
`afp_set_file_info_smoke` sends the WebSDK-documented NetWare AFP Set File
|
|
Information requests. It defaults to the AFP 2.0 subfunction and can exercise
|
|
the older AFP subfunction with `--afp09`:
|
|
|
|
```text
|
|
NCP 0x2222/35/09 AFP Set File Information
|
|
NCP 0x2222/35/16 AFP 2.0 Set File Information
|
|
```
|
|
|
|
The helper exercises two deliberately narrow write-safe AFP metadata subsets:
|
|
the file FinderInfo bitmap (`0x0020`), the file Attributes bitmap (`0x0001`)
|
|
restricted to metadata-only file flags: AFP Hidden, System, and Archive,
|
|
and the file modification timestamp bitmap (`0x0010`). It sends path-backed
|
|
raw `VOL:`-style requests, writes the 32-byte FinderInfo block to mars_nwe's
|
|
private `org.mars-nwe.afp.finder-info` metadata key, writes the narrow AFP
|
|
attribute word to `org.mars-nwe.afp.attributes`, routes modification timestamp
|
|
writes through the existing NetWare timestamp helper, and immediately verifies
|
|
the updates through AFP 2.0 Get File Information. On Linux the source-level `org.mars-nwe.afp.*` name is stored via the
|
|
portable `user.` xattr namespace by mars_nwe's local xattr wrapper, the same
|
|
pattern Netatalk uses for its `org.netatalk.*` metadata names.
|
|
|
|
Example:
|
|
|
|
```sh
|
|
./tests/linux/afp_set_file_info_smoke \
|
|
-S MARS -U SUPERVISOR -P secret \
|
|
--type TEXT --creator MARS \
|
|
SYS:PUBLIC/pmdflts.ini
|
|
```
|
|
|
|
|
|
|
|
The same FinderInfo payload can be sent through the older Set File Information
|
|
subfunction:
|
|
|
|
```sh
|
|
./tests/linux/afp_set_file_info_smoke \
|
|
-S MARS -U SUPERVISOR -P secret \
|
|
--afp09 --finder-info-only --type TEXT --creator MARS \
|
|
SYS:PUBLIC/pmdflts.ini
|
|
```
|
|
|
|
Verified runtime output:
|
|
|
|
```text
|
|
AFP Set File Info subfunction=0x10 path=SYS:PUBLIC/pmdflts.ini bitmap=0x4000 attrs=0x2000 create=0x5cbe access=0x5cbe modify=0x5cbea1ee backup=0x00000000 finder_type=TEXT finder_creator=MARS entry_id=0x00000004 verified
|
|
```
|
|
|
|
Server diagnostics show the effective resolved volume, the request volume byte,
|
|
the FinderInfo bitmap, and follow-up Get File Information verification with the
|
|
same namespace-derived Entry ID:
|
|
|
|
```text
|
|
AFP 2.0 Set File Information: vol=0 request_vol=0 entry=0x00000000 mask=0x4000 path='SYS:PUBLIC/pmdflts.ini' ...
|
|
AFP 2.0 Get File Information: vol=0 entry=0x00000000 mask=0xffff path='SYS:PUBLIC/pmdflts.ini' reply_entry=0x00000004
|
|
```
|
|
|
|
Linux xattr checks for the FinderInfo and cached Entry ID look like this:
|
|
|
|
```sh
|
|
getfattr -n user.org.mars-nwe.afp.finder-info -e hex /var/mars_nwe/SYS/public/pmdflts.ini
|
|
getfattr -n user.org.mars-nwe.afp.entry-id -e hex /var/mars_nwe/SYS/public/pmdflts.ini
|
|
```
|
|
|
|
For the verified FinderInfo smoke run, the FinderInfo xattr starts with
|
|
`TEXTMARS`:
|
|
|
|
```text
|
|
user.org.mars-nwe.afp.finder-info=0x544558544d415253000000000000000000000000000000000000000000000000
|
|
```
|
|
|
|
AFP Hidden can be tested without mutating DOS/NetWare mode bits:
|
|
|
|
```sh
|
|
./tests/linux/afp_set_file_info_smoke \
|
|
-S MARS -U SUPERVISOR -P secret \
|
|
--attributes-only --hidden \
|
|
SYS:PUBLIC/pmdflts.ini
|
|
|
|
getfattr -n user.org.mars-nwe.afp.attributes -e hex /var/mars_nwe/SYS/public/pmdflts.ini
|
|
```
|
|
|
|
The xattr payload is versioned. For an invisible file the expected Linux form
|
|
is:
|
|
|
|
```text
|
|
user.org.mars-nwe.afp.attributes=0x01000001
|
|
```
|
|
|
|
Use `--clear-hidden --attributes-only` to clear that bit; the same xattr then
|
|
stores `0x01000000`. The same helper can exercise the two additional
|
|
additional file attribute bits. System remains AFP metadata-only; Archive is
|
|
routed through the existing NetWare file attribute store (`FILE_ATTR_A`) rather
|
|
than the AFP metadata xattr:
|
|
|
|
```sh
|
|
./tests/linux/afp_set_file_info_smoke \
|
|
-S MARS -U SUPERVISOR -P secret \
|
|
--attributes-only --system \
|
|
SYS:PUBLIC/pmdflts.ini
|
|
|
|
./tests/linux/afp_set_file_info_smoke \
|
|
-S MARS -U SUPERVISOR -P secret \
|
|
--attributes-only --archive \
|
|
SYS:PUBLIC/pmdflts.ini
|
|
```
|
|
|
|
For System the AFP metadata xattr stores `0x01000004`. Archive is verified
|
|
through AFP Get File Information after updating the NetWare attribute store; it
|
|
no longer lives in `user.org.mars-nwe.afp.attributes`. Use `--clear-system`
|
|
and `--clear-archive` to remove those bits.
|
|
The older helper spellings `--backup` and `--clear-backup` remain accepted
|
|
as compatibility aliases, but the suite and documentation use Archive because
|
|
this bit is the AFP file attribute, not the separate AFP backup date/time field.
|
|
The helper verifies only the bit that a single probe sets or clears. Other
|
|
stored metadata bits are intentionally preserved, so a run can legitimately
|
|
report a combined attribute word while verifying only the targeted bit.
|
|
|
|
Verified runtime probes for the additional bits showed the expected AFP-visible
|
|
attribute words and server diagnostics. A later full-suite run also confirmed
|
|
that the helper must mask the targeted bit rather than compare the whole
|
|
attribute word: previously stored metadata bits can remain visible, so Hidden set/clear may
|
|
produce a combined attribute word while still being correct for the Invisible
|
|
bit. After Archive was mapped to the existing NetWare `FILE_ATTR_A` store, the
|
|
suite was rerun from the build-tree helper and completed with `failures=0`:
|
|
Archive set reported AFP-visible `attrs=0x2000`, Clear Archive reported
|
|
`attrs=0x0000`, and the final AFP metadata xattr stayed at `0x01000000`, proving
|
|
that Archive no longer lives in `user.org.mars-nwe.afp.attributes`.
|
|
|
|
```text
|
|
AFP Set File Info subfunction=0x10 path=SYS:PUBLIC/pmdflts.ini bitmap=0x0001 attrs=0x0004 finder_type=TEXT finder_creator=MARS entry_id=0x62ecb463 verified
|
|
AFP Set File Info subfunction=0x10 path=SYS:PUBLIC/pmdflts.ini bitmap=0x0001 attrs=0x0000 finder_type=TEXT finder_creator=MARS entry_id=0x62ecb463 verified
|
|
AFP Set File Info subfunction=0x10 path=SYS:PUBLIC/pmdflts.ini bitmap=0x0001 attrs=0x2000 finder_type=TEXT finder_creator=MARS entry_id=0x62ecb463 verified
|
|
AFP 2.0 Set File Information: vol=0 request_vol=0 entry=0x00000000 mask=0x0001 path='SYS:PUBLIC/pmdflts.ini' attributes attrs=0x8004
|
|
AFP 2.0 Set File Information: vol=0 request_vol=0 entry=0x00000000 mask=0x0001 path='SYS:PUBLIC/pmdflts.ini' attributes attrs=0x0004
|
|
AFP Set File Info subfunction=0x10 path=SYS:PUBLIC/pmdflts.ini bitmap=0x0001 attrs=0x2000 modify=0x576eb9aa finder_type=TEXT finder_creator=MARS entry_id=0x399193ed verified
|
|
AFP Set File Info subfunction=0x10 path=SYS:PUBLIC/pmdflts.ini bitmap=0x0001 attrs=0x0000 modify=0x576eb9aa finder_type=TEXT finder_creator=MARS entry_id=0x399193ed verified
|
|
user.org.mars-nwe.afp.attributes=0x01000000
|
|
AFP 2.0 Set File Information: vol=0 request_vol=0 entry=0x00000000 mask=0x0001 path='SYS:PUBLIC/pmdflts.ini' attributes attrs=0x8040
|
|
```
|
|
|
|
Modification timestamp writes are deliberately routed through the existing
|
|
NetWare `nw_utime_node()` path so trustee Modify rights and the established
|
|
`utime(2)` fallback behavior stay shared with classic NCP timestamp updates.
|
|
The first timestamp smoke uses a fixed Unix epoch that the helper converts into
|
|
the AFP/NW DOS date+time fields and verifies through the follow-up Get File
|
|
Information response:
|
|
|
|
```sh
|
|
./tests/linux/afp_set_file_info_smoke \
|
|
-S MARS -U SUPERVISOR -P secret \
|
|
--timestamp-only --mtime-epoch 1700000000 \
|
|
SYS:PUBLIC/pmdflts.ini
|
|
|
|
stat -c 'mtime_epoch=%Y mtime=%y' /var/mars_nwe/SYS/public/pmdflts.ini
|
|
```
|
|
|
|
This currently remains file-only and path-backed, just like the FinderInfo and
|
|
metadata-attribute Set File Information probes; directory timestamps and
|
|
Entry-ID-only Set File Information are left for later resolver work.
|
|
|
|
The legacy `0x09` endpoint is deliberately routed through the same narrow
|
|
implementation as AFP 2.0 `0x10`; it does not add create, rename, delete,
|
|
directory timestamp, or fork-write semantics.
|
|
|
|
All other Set File Information bitmap bits and AFP attribute bits, including
|
|
NoWrite, NoRename, NoDelete, NoCopy, and the computed data/resource-fork-open
|
|
flags, are intentionally rejected for now. That keeps create/access/backup
|
|
timestamps, DOS/NetWare mode-bit mapping, enforcement, resource-fork, and
|
|
Entry-ID-only write semantics out of this conservative smoke path.
|
|
|
|
If the server was built without the optional Netatalk/libatalk backend, use
|
|
`--allow-invalid-namespace` for the expected negative test. Use
|
|
`--allow-invalid-path` for path-resolution negative tests.
|
|
|
|
## AFP Get DOS Name From Entry ID smoke test
|
|
|
|
`afp_dos_name_smoke` exercises the WebSDK-documented NetWare AFP reverse
|
|
lookup:
|
|
|
|
```text
|
|
NCP 0x2222/35/18 AFP Get DOS Name From Entry ID
|
|
```
|
|
|
|
The request carries the AFP volume number and a 32-bit Macintosh directory
|
|
entry ID. The reply is a one-byte DOS path length followed by the DOS path
|
|
string for the matching entry. The smoke helper first resolves the supplied
|
|
`VOL:PATH` through AFP Get Entry ID From Path Name when `--entry-id` is not
|
|
provided, then calls AFP Get DOS Name From Entry ID and verifies that the
|
|
returned path matches the existing mars_nwe DOS namespace spelling without the
|
|
volume prefix.
|
|
|
|
Example:
|
|
|
|
```sh
|
|
./afp_dos_name_smoke -S MARS -U SUPERVISOR -P secret SYS:PUBLIC/pmdflts.ini
|
|
```
|
|
|
|
Expected output shape:
|
|
|
|
```text
|
|
AFP Get DOS Name From Entry ID volume=0 entry_id=0x00000004 path=PUBLIC/PMDFLTS.INI verified
|
|
```
|
|
|
|
A successful post-fix smoke-suite run confirmed the `namedos.c` alias path via
|
|
the existing mars_nwe namespace/basehandle resolver:
|
|
|
|
```text
|
|
AFP Get DOS Name From Entry ID volume=0 entry_id=0x00000004 path=PUBLIC/PMDFLTS.INI verified
|
|
AFP Get DOS Name From Entry ID: vol=0 entry=0x00000004 path='PUBLIC/PMDFLTS.INI'
|
|
```
|
|
|
|
This intentionally returns DOS namespace spelling rather than the raw Unix
|
|
realcase path (`public/pmdflts.ini`).
|
|
|
|
The server implementation deliberately reuses existing mars_nwe namespace
|
|
machinery. It first resolves the AFP Entry ID through
|
|
`map_directory_number_to_path()` and falls back to the old AFP metadata volume
|
|
walk only for legacy cached IDs. It does not create new AFP IDs while walking
|
|
the volume, keeping the reverse lookup read-only and avoiding a parallel AFP
|
|
path database.
|
|
|
|
### AFP attribute bit alignment with WebSDK
|
|
|
|
AFP Set/Get File Information now uses the documented WebSDK bitmaps for the
|
|
SetInfo request and for the returned attribute word. SetInfo request bits are
|
|
`0x0100` for Attributes, `0x1000` for Modify Date/Time, and `0x4000` for
|
|
FinderInfo. The attribute word maps `Hidden` (`0x0200`) to NetWare
|
|
`FILE_ATTR_H`, `System` (`0x0400`) to `FILE_ATTR_S`, and `Archive` (`0x2000`)
|
|
to `FILE_ATTR_A`. The smoke helper keeps `--hidden` as a compatibility
|
|
alias, but the suite uses `--hidden` / `--clear-hidden` because the value is the
|
|
NetWare/AFP Hidden attribute, not a separate Finder-only xattr.
|
|
|
|
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`. It also confirms the SetInfo request bitmaps `0x0100`
|
|
Attributes, `0x1000` Modify Date/Time, and `0x4000` FinderInfo. Since these
|
|
attributes now use the existing NetWare attribute path, the final
|
|
`user.org.mars-nwe.afp.attributes` dump is optional and may report `ENODATA`;
|
|
that is expected when no AFP-only attribute bits remain set.
|
|
|
|
### AFP Backup Date/Time smoke
|
|
|
|
`afp_set_file_info_smoke` supports the WebSDK Backup Date/Time request bitmap
|
|
`0x2000` via:
|
|
|
|
```sh
|
|
./afp_set_file_info_smoke \
|
|
-S MARS -U SUPERVISOR -P secret \
|
|
--backup-time-only --backup-time-epoch 1700000000 \
|
|
SYS:PUBLIC/pmdflts.ini
|
|
```
|
|
|
|
This is intentionally separate from the Archive attribute bit in the Attributes
|
|
word. The server stores Backup Date/Time through `nwarchive.c` and the Linux
|
|
suite dumps the corresponding xattr as:
|
|
|
|
```sh
|
|
getfattr -n user.org.mars-nwe.netware.archive -e hex /var/mars_nwe/SYS/public/pmdflts.ini
|
|
```
|
|
|
|
The expected AFP reply shows the same Backup Date/Time at offsets 28/30 of the
|
|
120-byte file information record, while Archive/Hidden/System attributes remain
|
|
mapped through the normal NetWare attribute store.
|
|
|
|
Runtime status: the Backup Date/Time smoke run is verified with `failures=0`.
|
|
The report showed `bitmap=0x2000`, `backup=0x576eb9aa`, and the backing xattr
|
|
`user.org.mars-nwe.netware.archive=0x01036e57aab900000000` after setting epoch
|
|
`1700000000`.
|
|
|
|
|
|
### AFP Access Date/Time smoke
|
|
|
|
`afp_set_file_info_smoke` supports the WebSDK Access Date/Time request bitmap
|
|
`0x0400` via:
|
|
|
|
```sh
|
|
./afp_set_file_info_smoke \
|
|
-S MARS -U SUPERVISOR -P secret \
|
|
--access-time-only --access-time-epoch 1700000000 \
|
|
SYS:PUBLIC/pmdflts.ini
|
|
```
|
|
|
|
The server stores Access Date/Time through the existing POSIX `st_atime` path,
|
|
preserving `st_mtime` with `utime()` and enforcing trustee Modify rights before
|
|
changing the timestamp. The AFP file-information record exposes the Access
|
|
Date at offset 22; no AFP-specific xattr is added for this NetWare-semantic
|
|
timestamp.
|
|
|
|
Runtime status: the Access Date/Time smoke run is verified with `failures=0`.
|
|
The report showed `bitmap=0x0400`, `access=0x576e`, and no AFP-only xattr for
|
|
this timestamp after setting epoch `1700000000`.
|
|
|
|
### AFP Create Date/Time smoke
|
|
|
|
`afp_set_file_info_smoke` supports the WebSDK Create Date/Time request bitmap
|
|
`0x0800` via:
|
|
|
|
```sh
|
|
./afp_set_file_info_smoke \
|
|
-S MARS -U SUPERVISOR -P secret \
|
|
--create-time-only --create-time-epoch 1700000000 \
|
|
SYS:PUBLIC/pmdflts.ini
|
|
```
|
|
|
|
The server stores Create Date/Time through `nwarchive.c` file-info metadata
|
|
(`user.org.mars-nwe.netware.fileinfo`) using `mars_nwe_set_file_info()`. The
|
|
AFP file-information record exposes the Create Date at offset 20; the matching
|
|
Create Time is still persisted in the shared NetWare file-info metadata so
|
|
classic NetWare file-info paths can return it. No AFP-specific xattr is added
|
|
for this NetWare-semantic timestamp.
|
|
|
|
Runtime status: the Create Date/Time smoke run is verified with `failures=0`.
|
|
The report showed `bitmap=0x0800`, `create=0x576e`, and the backing xattr
|
|
`user.org.mars-nwe.netware.fileinfo=0x01036e57aab90000000000000000` after
|
|
setting epoch `1700000000`.
|