nwconn: align AFP attribute bits with WebSDK
All checks were successful
Source release / source-package (push) Successful in 46s

The WebSDK/NCP AFP File Information records use a distinct SetInfo request bitmap and attribute word.  The previous smoke-oriented implementation reused the low response-bit positions for Set Attributes, Modify Date/Time, FinderInfo, Hidden/Invisible, System, and Archive.  That made the current tests pass, but it was not faithful to the documented header semantics and risked keeping AFP metadata parallel to existing NetWare attributes.

Switch Set File Information to the documented request bitmap values: 0x0100 for Attributes, 0x1000 for Modify Date/Time, and 0x4000 for FinderInfo.  Switch the AFP attribute word to the documented NetWare-style bits: Hidden 0x0200, System 0x0400, Subdirectory 0x1000, and Archive 0x2000.

Map Hidden, System, and Archive through the existing NetWare attribute store via FILE_ATTR_H, FILE_ATTR_S, and FILE_ATTR_A.  This keeps AFP Set/Get/Scan aligned with mars_nwe's existing attribute helper instead of maintaining duplicate AFP-only xattr state.  FinderInfo remains AFP metadata and still uses the Modify-rights gate added earlier.

Update the Linux smoke helper and suite to use --hidden / --clear-hidden while keeping --invisible / --clear-invisible as compatibility aliases.  Document the corrected WebSDK bit values and the convergence rule that NetWare attributes must use mars_nwe NetWare helpers.

Tests: git diff --check; bash -n tests/linux/afp_smoke_suite.sh; gcc -Iinclude -I/mnt/data/stubs -fsyntax-only tests/linux/afp_set_file_info_smoke.c
This commit is contained in:
OpenAI
2026-05-30 15:46:23 +00:00
committed by Mario Fetka
parent fb4934fddc
commit 55fdf64c8e
6 changed files with 122 additions and 94 deletions

33
TODO.md
View File

@@ -274,15 +274,15 @@ Current status:
- `AFP Set File Information` (`0x09`) and `AFP 2.0 Set File Information`
(`0x10`) are implemented only for path-backed file metadata smoke writes:
the FinderInfo bitmap (`0x0020`) and the AFP
Attributes bitmap (`0x0001`) restricted to Finder Invisible, System, and
Attributes bitmap (`0x0001`) restricted to AFP Hidden, System, and
Archive. Archive is mapped to the existing NetWare `FILE_ATTR_A` attribute
path, while Invisible and System remain mars_nwe AFP metadata xattr bits. Linux
path, while Hidden and System remain mars_nwe AFP metadata xattr bits. Linux
smoke coverage exists in `tests/linux/afp_set_file_info_smoke`; runtime
FinderInfo coverage is green for `SYS:PUBLIC/pmdflts.ini` with Finder type
`TEXT` and creator `MARS`. The helper writes 32 bytes of FinderInfo to
`org.mars-nwe.afp.finder-info`, stores AFP-only Invisible/System bits in
`org.mars-nwe.afp.finder-info`, stores AFP-only Hidden/System bits in
`org.mars-nwe.afp.attributes`, maps Archive through the existing NetWare
attribute store, and verifies the result through AFP 2.0 Get File Information. The smoke-suite report helper now includes AFP 2.0 FinderInfo, legacy AFP `0x09` FinderInfo, AFP 2.0 Invisible/System/Archive set/clear probes,
attribute store, and verifies the result through AFP 2.0 Get File Information. The smoke-suite report helper now includes AFP 2.0 FinderInfo, legacy AFP `0x09` FinderInfo, AFP 2.0 Hidden/System/Archive set/clear probes,
and legacy AFP `0x09` Invisible set/clear probes, and has green
`failures=0` runs for `SYS:PUBLIC/pmdflts.ini`; the latest run was from the
build-tree copy of `afp_smoke_suite.sh` after the CMake sync fix and confirms
@@ -356,7 +356,7 @@ Follow-up:
`0x7b9c42e1` Entry ID. 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. FinderInfo plus the Finder Invisible/System/Archive AFP attributes now have
continuation token. 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
@@ -406,12 +406,12 @@ Refactor/wrapper follow-up:
reusing existing mars_nwe volume, namespace, and directory-handle helpers.
- 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 Invisible/System xattr writes are now gated
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. Archive is already mapped to `FILE_ATTR_A`; ReadOnly,
Hidden, System, ExecuteOnly, and Shareable still need either a real mapping
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()`, while Create, Access, and Backup
@@ -431,7 +431,7 @@ Refactor/wrapper follow-up:
AFP Set File Information metadata-rights convergence:
- AFP FinderInfo writes and AFP-only Invisible/System attribute xattr writes no
- 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.*`
@@ -442,14 +442,14 @@ AFP Set File Information metadata-rights convergence:
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, Invisible, and System writes as a user that is expected to lack
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, Invisible, and System Set
`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
@@ -479,3 +479,14 @@ 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.

View File

@@ -22,11 +22,11 @@
#define MARS_NWE_AFP_ENTRY_ID_VERSION 1
#define MARS_NWE_AFP_ATTRIBUTES_VERSION 1
#define NWATALK_AFP_ATTR_INVISIBLE 0x0001
#define NWATALK_AFP_ATTR_SYSTEM 0x0004
#define NWATALK_AFP_ATTR_SETCLR 0x8000
#define NWATALK_AFP_ATTR_HIDDEN 0x0200
#define NWATALK_AFP_ATTR_SYSTEM 0x0400
#define NWATALK_AFP_ATTR_SETCLR 0x8000
#define NWATALK_AFP_ATTR_STORED_MASK \
(NWATALK_AFP_ATTR_INVISIBLE | NWATALK_AFP_ATTR_SYSTEM)
(NWATALK_AFP_ATTR_HIDDEN | NWATALK_AFP_ATTR_SYSTEM)
typedef struct {
uint8 version;

View File

@@ -1112,34 +1112,34 @@ static void afp_leaf_name_from_path(uint8 *dst, int dst_len,
afp_copy_fixed_name(dst, dst_len, path + start, end - start);
}
#define AFP_FILE_BITMAP_ATTRIBUTES 0x0001
#define AFP_FILE_BITMAP_MODIFY_DATE 0x0010
#define AFP_FILE_BITMAP_FINDER_INFO 0x0020
#define AFP_ATTR_INVISIBLE 0x0001
#define AFP_ATTR_SYSTEM 0x0004
#define AFP_ATTR_ARCHIVE 0x0040
#define AFP_FILE_BITMAP_ATTRIBUTES 0x0100
#define AFP_FILE_BITMAP_MODIFY_DATE 0x1000
#define AFP_FILE_BITMAP_FINDER_INFO 0x4000
#define AFP_ATTR_HIDDEN 0x0200
#define AFP_ATTR_SYSTEM 0x0400
#define AFP_ATTR_SUBDIRECTORY 0x1000
#define AFP_ATTR_ARCHIVE 0x2000
#define AFP_ATTR_SETCLR 0x8000
#define AFP_ATTR_STORED_MASK \
(AFP_ATTR_INVISIBLE | AFP_ATTR_SYSTEM | AFP_ATTR_ARCHIVE)
#define AFP_ATTR_XATTR_MASK \
(AFP_ATTR_INVISIBLE | AFP_ATTR_SYSTEM)
#define AFP_ATTR_NETWARE_MASK \
(AFP_ATTR_HIDDEN | AFP_ATTR_SYSTEM | AFP_ATTR_ARCHIVE)
static uint16 afp_basic_attributes(int volume, const char *unixname, const struct stat *stb)
{
uint16 attributes = 0;
if (S_ISDIR(stb->st_mode))
attributes |= 0x0400; /* AFP_SA_SUBDIR */
attributes |= AFP_ATTR_SUBDIRECTORY;
if (!S_ISDIR(stb->st_mode)) {
uint16 stored_attrs = 0;
uint32 nw_attrs = get_nw_attrib_dword(volume, (char *)unixname,
(struct stat *)stb);
if (nw_attrs & FILE_ATTR_H)
attributes |= AFP_ATTR_HIDDEN;
if (nw_attrs & FILE_ATTR_S)
attributes |= AFP_ATTR_SYSTEM;
if (nw_attrs & FILE_ATTR_A)
attributes |= AFP_ATTR_ARCHIVE;
if (!nwatalk_get_afp_attributes(unixname, &stored_attrs))
attributes |= stored_attrs;
}
return(attributes);
@@ -1290,18 +1290,29 @@ static int afp_get_file_information(uint8 *afp_req, int afp_len,
}
static int afp_set_netware_archive_attribute(int volume, char *unixname,
struct stat *stb,
uint16 requested_attrs)
static int afp_set_netware_attributes(int volume, char *unixname,
struct stat *stb,
uint16 requested_attrs)
{
uint32 nw_attrs;
uint16 requested_bits;
uint32 mapped_bits = 0;
if (!unixname || !stb) return(-0x9c);
requested_bits = requested_attrs & ~AFP_ATTR_SETCLR;
if (requested_bits & AFP_ATTR_HIDDEN) mapped_bits |= FILE_ATTR_H;
if (requested_bits & AFP_ATTR_SYSTEM) mapped_bits |= FILE_ATTR_S;
if (requested_bits & AFP_ATTR_ARCHIVE) mapped_bits |= FILE_ATTR_A;
if (!mapped_bits) return(0);
nw_attrs = get_nw_attrib_dword(volume, unixname, stb);
if (requested_attrs & AFP_ATTR_SETCLR)
nw_attrs |= FILE_ATTR_A;
nw_attrs |= mapped_bits;
else
nw_attrs &= ~FILE_ATTR_A;
nw_attrs &= ~mapped_bits;
return(set_nw_attrib_word(volume, unixname, stb, (int)(nw_attrs & 0xffff)));
}
@@ -1400,13 +1411,13 @@ static int afp_set_file_information(uint8 *afp_req, int afp_len,
if (request_mask & AFP_FILE_BITMAP_ATTRIBUTES) {
uint16 requested_attrs = GET_BE16(afp_req + data_off);
uint16 requested_bits = requested_attrs & ~AFP_ATTR_SETCLR;
if (requested_bits & ~AFP_ATTR_STORED_MASK) {
if (requested_bits & ~AFP_ATTR_NETWARE_MASK) {
XDPRINTF((2,0, "%s rejected: unsupported AFP attributes attrs=0x%04x path='%s'",
call_name, requested_attrs, visable_data(afp_req + 9, path_len)));
return(-0x9c);
}
if (requested_bits & AFP_ATTR_XATTR_MASK)
needs_afp_metadata_modify = 1;
/* Attribute writes are routed through set_nw_attrib_word(), which performs
* the NetWare Modify-rights check. FinderInfo remains AFP metadata. */
data_off += 2;
}
if ((request_mask & AFP_FILE_BITMAP_MODIFY_DATE) && afp_len < data_off + 4) {
@@ -1461,17 +1472,12 @@ static int afp_set_file_information(uint8 *afp_req, int afp_len,
uint16 requested_attrs = GET_BE16(afp_req + data_off);
uint16 requested_set_bits = requested_attrs & ~AFP_ATTR_SETCLR;
log_attrs = requested_attrs;
if (requested_set_bits & AFP_ATTR_ARCHIVE) {
result = afp_set_netware_archive_attribute(path_volume, unixname,
&stbuff, requested_attrs);
if (result < 0)
return(result);
}
if (requested_set_bits & AFP_ATTR_XATTR_MASK) {
uint16 xattr_attrs = requested_attrs & (AFP_ATTR_SETCLR | AFP_ATTR_XATTR_MASK);
result = nwatalk_set_afp_attributes(unixname, xattr_attrs);
if (requested_set_bits & AFP_ATTR_NETWARE_MASK) {
result = afp_set_netware_attributes(path_volume, unixname,
&stbuff, requested_attrs);
if (result < 0)
return(result);
if (!stat(unixname, &stbuff)) {}
}
data_off += 2;
}

View File

@@ -63,8 +63,8 @@ Example from the build `tests/linux` directory:
The report includes AFP Entry ID, Entry ID From NetWare Handle, Get File
Information, Scan File Information, Alloc Temporary Directory Handle, Open File
Fork, FinderInfo Set File Information for both AFP 2.0 (`0x10`) and the legacy AFP
Set File Information (`0x09`), AFP 2.0 Invisible/System/Archive Set/Clear File
Information, legacy AFP `0x09` Invisible Set/Clear coverage, and the Linux xattr
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
@@ -75,7 +75,7 @@ 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: System (`0x0004`) and Archive (`0x0040`).
`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
@@ -115,7 +115,7 @@ 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 Invisible/System metadata. Archive uses the existing NetWare attribute
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.
@@ -125,7 +125,7 @@ A verified rights-negative smoke run with `--readonly-user NOPASSUSER`,
`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,
Invisible, and System metadata writes with completion `0x8c` while the
Hidden, and System metadata writes with completion `0x8c` while the
SUPERVISOR positive path still succeeds:
```text
@@ -153,7 +153,7 @@ 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 Invisible set/clear. The relevant Linux xattr checks
Information, and Finder Hidden set/clear. The relevant Linux xattr checks
from that run were:
```text
@@ -166,13 +166,13 @@ 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 Invisible/System/Archive attribute probes.
`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 Invisible set/clear, 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:
@@ -182,7 +182,7 @@ AFP Set File Info subfunction=0x09 path=SYS:PUBLIC/pmdflts.ini bitmap=0x0001 att
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=0x0040 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
@@ -569,7 +569,7 @@ 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: Finder Invisible, System, and Archive,
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
@@ -637,12 +637,12 @@ For the verified FinderInfo smoke run, the FinderInfo xattr starts with
user.org.mars-nwe.afp.finder-info=0x544558544d415253000000000000000000000000000000000000000000000000
```
Finder Invisible can be tested without mutating DOS/NetWare mode bits:
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 --invisible \
--attributes-only --hidden \
SYS:PUBLIC/pmdflts.ini
getfattr -n user.org.mars-nwe.afp.attributes -e hex /var/mars_nwe/SYS/public/pmdflts.ini
@@ -655,7 +655,7 @@ is:
user.org.mars-nwe.afp.attributes=0x01000001
```
Use `--clear-invisible --attributes-only` to clear that bit; the same xattr then
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
@@ -687,21 +687,21 @@ 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 Invisible set/clear may
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=0x0040`, Clear Archive reported
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=0x0040 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=0x0040 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=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
@@ -789,3 +789,14 @@ mars_nwe/Netatalk AFP ID, which is the normal state after the Entry ID, Get File
Information, or Scan File Information smoke probes. This keeps the reverse
lookup read-only and avoids populating entry-id xattrs across a whole volume as a
side effect of one DOS-name lookup.
### 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.

View File

@@ -23,14 +23,14 @@
#define AFP20_GET_FILE_INFORMATION 0x0f
#define AFP_SET_FILE_INFORMATION 0x09
#define AFP20_SET_FILE_INFORMATION 0x10
#define AFP_ATTRIBUTES_MASK 0x0001
#define AFP_MODIFY_DATE_MASK 0x0010
#define AFP_FINDER_INFO_MASK 0x0020
#define AFP_ATTR_INVISIBLE 0x0001
#define AFP_ATTR_SYSTEM 0x0004
#define AFP_ATTR_ARCHIVE 0x0040
#define AFP_ATTRIBUTES_MASK 0x0100
#define AFP_MODIFY_DATE_MASK 0x1000
#define AFP_FINDER_INFO_MASK 0x4000
#define AFP_ATTR_HIDDEN 0x0200
#define AFP_ATTR_SYSTEM 0x0400
#define AFP_ATTR_ARCHIVE 0x2000
#define AFP_ATTR_SETCLR 0x8000
#define AFP_ATTR_STORED_MASK (AFP_ATTR_INVISIBLE | AFP_ATTR_SYSTEM | AFP_ATTR_ARCHIVE)
#define AFP_ATTR_STORED_MASK (AFP_ATTR_HIDDEN | AFP_ATTR_SYSTEM | AFP_ATTR_ARCHIVE)
#define AFP_REPLY_LEN 120
#define NWE_INVALID_NAMESPACE 0xbf
#define NWE_INVALID_PATH 0x9c
@@ -40,7 +40,7 @@ static void usage(const char *prog)
fprintf(stderr,
"Usage: %s [--afp09|--afp20] [--expect-completion CODE] [--allow-invalid-namespace] [--allow-invalid-path] "
"[--volume N] [--entry-id ID] [--type FOUR] [--creator FOUR] "
"[--invisible|--clear-invisible|--system|--clear-system|--archive|--clear-archive] "
"[--hidden|--clear-hidden|--invisible|--clear-invisible|--system|--clear-system|--archive|--clear-archive] "
"[--mtime-epoch SECONDS] [--finder-info-only|--attributes-only|--timestamp-only] "
"[ncpfs options] PATH\n"
"\n"
@@ -49,7 +49,7 @@ static void usage(const char *prog)
"\n"
"Examples:\n"
" %s -S MARS -U SUPERVISOR -P secret --type TEXT --creator MARS SYS:PUBLIC/pmdflts.ini\n"
" %s -S MARS -U SUPERVISOR -P secret --invisible --attributes-only SYS:PUBLIC/pmdflts.ini\n"
" %s -S MARS -U SUPERVISOR -P secret --hidden --attributes-only SYS:PUBLIC/pmdflts.ini\n"
" %s -S MARS -U SUPERVISOR -P secret --archive --attributes-only SYS:PUBLIC/pmdflts.ini\n"
" %s -S MARS -U SUPERVISOR -P secret --mtime-epoch 1700000000 --timestamp-only SYS:PUBLIC/pmdflts.ini\n"
" %s --allow-invalid-namespace -S MARS SYS:PUBLIC/pmdflts.ini\n"
@@ -226,15 +226,15 @@ int main(int argc, char **argv)
ncp_close(conn);
return 2;
}
} else if (!strcmp(argv[i], "--invisible")) {
} else if (!strcmp(argv[i], "--hidden") || !strcmp(argv[i], "--invisible")) {
request_mask |= AFP_ATTRIBUTES_MASK;
attr_request = AFP_ATTR_SETCLR | AFP_ATTR_INVISIBLE;
attr_verify_mask = AFP_ATTR_INVISIBLE;
attr_expected = AFP_ATTR_INVISIBLE;
} else if (!strcmp(argv[i], "--clear-invisible")) {
attr_request = AFP_ATTR_SETCLR | AFP_ATTR_HIDDEN;
attr_verify_mask = AFP_ATTR_HIDDEN;
attr_expected = AFP_ATTR_HIDDEN;
} else if (!strcmp(argv[i], "--clear-hidden") || !strcmp(argv[i], "--clear-invisible")) {
request_mask |= AFP_ATTRIBUTES_MASK;
attr_request = AFP_ATTR_INVISIBLE;
attr_verify_mask = AFP_ATTR_INVISIBLE;
attr_request = AFP_ATTR_HIDDEN;
attr_verify_mask = AFP_ATTR_HIDDEN;
attr_expected = 0;
} else if (!strcmp(argv[i], "--system")) {
request_mask |= AFP_ATTRIBUTES_MASK;

View File

@@ -339,28 +339,28 @@ run_cmd \
--afp09 --finder-info-only --type "$FINDER_TYPE" --creator "$FINDER_CREATOR" "$NETWARE_PATH"
run_cmd \
"AFP Set File Information Invisible" \
"./afp_set_file_info_smoke $COMMON_PRINT --attributes-only --invisible '$NETWARE_PATH'" \
"AFP Set File Information Hidden" \
"./afp_set_file_info_smoke $COMMON_PRINT --attributes-only --hidden '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--attributes-only --invisible "$NETWARE_PATH"
--attributes-only --hidden "$NETWARE_PATH"
run_cmd \
"AFP Set File Information Clear Invisible" \
"./afp_set_file_info_smoke $COMMON_PRINT --attributes-only --clear-invisible '$NETWARE_PATH'" \
"AFP Set File Information Clear Hidden" \
"./afp_set_file_info_smoke $COMMON_PRINT --attributes-only --clear-hidden '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--attributes-only --clear-invisible "$NETWARE_PATH"
--attributes-only --clear-hidden "$NETWARE_PATH"
run_cmd \
"AFP Set File Information Invisible legacy" \
"./afp_set_file_info_smoke $COMMON_PRINT --afp09 --attributes-only --invisible '$NETWARE_PATH'" \
"AFP Set File Information Hidden legacy" \
"./afp_set_file_info_smoke $COMMON_PRINT --afp09 --attributes-only --hidden '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--afp09 --attributes-only --invisible "$NETWARE_PATH"
--afp09 --attributes-only --hidden "$NETWARE_PATH"
run_cmd \
"AFP Set File Information Clear Invisible legacy" \
"./afp_set_file_info_smoke $COMMON_PRINT --afp09 --attributes-only --clear-invisible '$NETWARE_PATH'" \
"AFP Set File Information Clear Hidden legacy" \
"./afp_set_file_info_smoke $COMMON_PRINT --afp09 --attributes-only --clear-hidden '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \
--afp09 --attributes-only --clear-invisible "$NETWARE_PATH"
--afp09 --attributes-only --clear-hidden "$NETWARE_PATH"
run_cmd \
"AFP Set File Information Modify Timestamp" \
@@ -407,11 +407,11 @@ if [ -n "$READONLY_USER" ]; then
-S "$SERVER" -U "$READONLY_USER" "${READONLY_AUTH_ARGS[@]}" \
--finder-info-only --type "$FINDER_TYPE" --creator "$FINDER_CREATOR" "$NETWARE_PATH"
run_cmd \
"AFP metadata Modify rights rejected: Invisible" \
"./afp_set_file_info_smoke --expect-completion 0x8c $READONLY_PRINT --attributes-only --invisible '$NETWARE_PATH'" \
"AFP attribute Modify rights rejected: Hidden" \
"./afp_set_file_info_smoke --expect-completion 0x8c $READONLY_PRINT --attributes-only --hidden '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_set_file_info_smoke" --expect-completion 0x8c \
-S "$SERVER" -U "$READONLY_USER" "${READONLY_AUTH_ARGS[@]}" \
--attributes-only --invisible "$NETWARE_PATH"
--attributes-only --hidden "$NETWARE_PATH"
run_cmd \
"AFP metadata Modify rights rejected: System" \
"./afp_set_file_info_smoke --expect-completion 0x8c $READONLY_PRINT --attributes-only --system '$NETWARE_PATH'" \