From 068afd5d8a450847929794dc77b24a5b01079d81 Mon Sep 17 00:00:00 2001 From: OpenAI Date: Sat, 30 May 2026 12:46:31 +0000 Subject: [PATCH] nwconn: rename AFP backup attribute to archive The NWAFP Set File Information attribute word uses a metadata bit that our earlier smoke code called Backup. That name is too easy to confuse with the distinct AFP backup date/time fields in the Set/Get File Information records. Treat the bit consistently as the Archive attribute in the server constants, Netatalk/xattr helper mask, Linux smoke helper, smoke suite, and documentation. Keep --backup and --clear-backup as compatibility aliases in afp_set_file_info_smoke so existing local invocations continue to work, but make the generated suite use --archive and --clear-archive. The source-level xattr payload remains unchanged: org.mars-nwe.afp.attributes still stores the same versioned attribute word and bit value 0x0040. 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 --- TODO.md | 17 ++++++++++------- src/nwatalk.c | 4 ++-- src/nwconn.c | 6 +++--- tests/linux/README.md | 23 +++++++++++++---------- tests/linux/afp_set_file_info_smoke.c | 22 +++++++++++----------- tests/linux/afp_smoke_suite.sh | 12 ++++++------ 6 files changed, 45 insertions(+), 39 deletions(-) diff --git a/TODO.md b/TODO.md index be16c4a..7d66eb4 100644 --- a/TODO.md +++ b/TODO.md @@ -273,13 +273,13 @@ Current status: (`0x10`) are implemented only for path-backed file metadata smoke writes: the FinderInfo bitmap (`0x0020`) and the AFP Attributes bitmap (`0x0001`) restricted to metadata-only file bits: Finder - Invisible, System, and Backup. Linux + Invisible, System, and Archive. 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 the narrow attribute word in `org.mars-nwe.afp.attributes`, 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/Backup set/clear probes, + 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, 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 @@ -294,13 +294,16 @@ Current status: `fallback` marker on that first verification Get File Information diagnostic describes the entry-id origin, not the FinderInfo write result. Follow-up probes should read the cached mars_nwe entry id and omit the fallback marker. - System and Backup are now supported by the same narrow xattr-only attribute - path; runtime probes verified System set/clear and Backup set with AFP-visible + System and Archive are now supported by the same narrow xattr-only attribute + path; runtime probes verified System set/clear and Archive set with AFP-visible attrs `0x0004`, `0x0000`, and `0x0040`, with server diagnostics showing the matching WebSDK SETCLR forms `0x8004`, `0x0004`, and `0x8040`. The smoke helper verifies the targeted attribute bit by mask instead of comparing the - full AFP attribute word, because other stored metadata bits such as Backup may - legitimately remain set while Invisible or System is being tested. All other Set File Information bits and AFP attribute bits remain + full AFP attribute word, because other stored metadata bits such as Archive may + legitimately remain set while Invisible or System is being tested. The earlier + smoke-helper `--backup` spelling is only kept as an alias; new docs and the + suite use Archive to avoid confusing this AFP attribute with the separate + backup date/time fields. All other Set File Information bits and AFP attribute bits remain rejected until their write/enforcement semantics are explicitly designed. - The AFP dispatcher now decodes the WebSDK/NWAFP subfunction number in diagnostics so real client probes can be mapped to the corresponding AFP @@ -339,7 +342,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/Backup AFP attributes now have + continuation token. FinderInfo plus the Finder Invisible/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 diff --git a/src/nwatalk.c b/src/nwatalk.c index d4c5e9d..a39a246 100644 --- a/src/nwatalk.c +++ b/src/nwatalk.c @@ -24,10 +24,10 @@ #define NWATALK_AFP_ATTR_INVISIBLE 0x0001 #define NWATALK_AFP_ATTR_SYSTEM 0x0004 -#define NWATALK_AFP_ATTR_BACKUP 0x0040 +#define NWATALK_AFP_ATTR_ARCHIVE 0x0040 #define NWATALK_AFP_ATTR_SETCLR 0x8000 #define NWATALK_AFP_ATTR_STORED_MASK \ - (NWATALK_AFP_ATTR_INVISIBLE | NWATALK_AFP_ATTR_SYSTEM | NWATALK_AFP_ATTR_BACKUP) + (NWATALK_AFP_ATTR_INVISIBLE | NWATALK_AFP_ATTR_SYSTEM | NWATALK_AFP_ATTR_ARCHIVE) typedef struct { uint8 version; diff --git a/src/nwconn.c b/src/nwconn.c index d647379..811c88a 100644 --- a/src/nwconn.c +++ b/src/nwconn.c @@ -1099,10 +1099,10 @@ static int afp_get_file_information(uint8 *afp_req, int afp_len, #define AFP_FILE_BITMAP_FINDER_INFO 0x0020 #define AFP_ATTR_INVISIBLE 0x0001 #define AFP_ATTR_SYSTEM 0x0004 -#define AFP_ATTR_BACKUP 0x0040 +#define AFP_ATTR_ARCHIVE 0x0040 #define AFP_ATTR_SETCLR 0x8000 #define AFP_ATTR_STORED_MASK \ - (AFP_ATTR_INVISIBLE | AFP_ATTR_SYSTEM | AFP_ATTR_BACKUP) + (AFP_ATTR_INVISIBLE | AFP_ATTR_SYSTEM | AFP_ATTR_ARCHIVE) static int afp_set_file_information(uint8 *afp_req, int afp_len, const char *call_name) @@ -3394,7 +3394,7 @@ static int handle_ncp_serv(void) * SYS:-style path inputs. AFP Set File Information (0x09) * and AFP 2.0 Set File Information (0x10) accept only * FinderInfo plus the - * metadata-only Invisible/System/Backup file attributes as + * metadata-only Invisible/System/Archive file attributes as * xattr write smoke paths. AFP 2.0 Get File Information * uses the same request/reply layout for this read-only * path-backed subset, so route it through the same helper diff --git a/tests/linux/README.md b/tests/linux/README.md index 9f44ee7..9d39957 100644 --- a/tests/linux/README.md +++ b/tests/linux/README.md @@ -63,7 +63,7 @@ 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/Backup Set/Clear File +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 checks for: @@ -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 Backup (`0x0040`). +`afp_set_file_info_smoke` supports: System (`0x0004`) and Archive (`0x0040`). 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 @@ -104,14 +104,14 @@ 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/Backup attribute probes. +`mask=0x0001` for the Invisible/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 -System set/clear, and AFP 2.0 Backup set/clear while leaving the final attribute +System set/clear, and AFP 2.0 Archive set/clear while leaving the final attribute xattr clear: ```text @@ -490,7 +490,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 Backup, +restricted to metadata-only file flags: Finder Invisible, 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 @@ -590,21 +590,24 @@ attribute mutation: ./tests/linux/afp_set_file_info_smoke \ -S MARS -U SUPERVISOR -P secret \ - --attributes-only --backup \ + --attributes-only --archive \ SYS:PUBLIC/pmdflts.ini ``` -For System the xattr value stores `0x01000004`; for Backup it stores -`0x01000040`. Use `--clear-system` and `--clear-backup` to remove those bits. +For System the xattr value stores `0x01000004`; for Archive it stores +`0x01000040`. 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 AFP metadata bits are intentionally preserved, so a run that starts with -Backup already set can legitimately report `attrs=0x0041` while verifying that +Archive already set can legitimately report `attrs=0x0041` while verifying that Invisible was set. 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: Backup persisted as `0x0040`, so Invisible set/clear produced +attribute word: Archive persisted as `0x0040`, so Invisible set/clear produced `0x0041` and `0x0040` while still being correct for the Invisible bit. ```text diff --git a/tests/linux/afp_set_file_info_smoke.c b/tests/linux/afp_set_file_info_smoke.c index 7bcaee0..a4d34f6 100644 --- a/tests/linux/afp_set_file_info_smoke.c +++ b/tests/linux/afp_set_file_info_smoke.c @@ -28,9 +28,9 @@ #define AFP_FINDER_INFO_MASK 0x0020 #define AFP_ATTR_INVISIBLE 0x0001 #define AFP_ATTR_SYSTEM 0x0004 -#define AFP_ATTR_BACKUP 0x0040 +#define AFP_ATTR_ARCHIVE 0x0040 #define AFP_ATTR_SETCLR 0x8000 -#define AFP_ATTR_STORED_MASK (AFP_ATTR_INVISIBLE | AFP_ATTR_SYSTEM | AFP_ATTR_BACKUP) +#define AFP_ATTR_STORED_MASK (AFP_ATTR_INVISIBLE | 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] [--allow-invalid-namespace] [--allow-invalid-path] " "[--volume N] [--entry-id ID] [--type FOUR] [--creator FOUR] " - "[--invisible|--clear-invisible|--system|--clear-system|--backup|--clear-backup] " + "[--invisible|--clear-invisible|--system|--clear-system|--archive|--clear-archive] " "[--mtime-epoch SECONDS] [--finder-info-only|--attributes-only|--timestamp-only] " "[ncpfs options] PATH\n" "\n" @@ -50,7 +50,7 @@ static void usage(const char *prog) "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 --backup --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", prog, prog, prog, prog, prog, prog); @@ -236,15 +236,15 @@ int main(int argc, char **argv) attr_request = AFP_ATTR_SYSTEM; attr_verify_mask = AFP_ATTR_SYSTEM; attr_expected = 0; - } else if (!strcmp(argv[i], "--backup")) { + } else if (!strcmp(argv[i], "--archive") || !strcmp(argv[i], "--backup")) { request_mask |= AFP_ATTRIBUTES_MASK; - attr_request = AFP_ATTR_SETCLR | AFP_ATTR_BACKUP; - attr_verify_mask = AFP_ATTR_BACKUP; - attr_expected = AFP_ATTR_BACKUP; - } else if (!strcmp(argv[i], "--clear-backup")) { + attr_request = AFP_ATTR_SETCLR | AFP_ATTR_ARCHIVE; + attr_verify_mask = AFP_ATTR_ARCHIVE; + attr_expected = AFP_ATTR_ARCHIVE; + } else if (!strcmp(argv[i], "--clear-archive") || !strcmp(argv[i], "--clear-backup")) { request_mask |= AFP_ATTRIBUTES_MASK; - attr_request = AFP_ATTR_BACKUP; - attr_verify_mask = AFP_ATTR_BACKUP; + attr_request = AFP_ATTR_ARCHIVE; + attr_verify_mask = AFP_ATTR_ARCHIVE; attr_expected = 0; } else if (!strcmp(argv[i], "--mtime-epoch")) { uint32_t epoch; diff --git a/tests/linux/afp_smoke_suite.sh b/tests/linux/afp_smoke_suite.sh index be8b751..275206d 100755 --- a/tests/linux/afp_smoke_suite.sh +++ b/tests/linux/afp_smoke_suite.sh @@ -289,16 +289,16 @@ run_cmd \ --attributes-only --clear-system "$NETWARE_PATH" run_cmd \ - "AFP Set File Information Backup" \ - "./afp_set_file_info_smoke $COMMON_PRINT --attributes-only --backup '$NETWARE_PATH'" \ + "AFP Set File Information Archive" \ + "./afp_set_file_info_smoke $COMMON_PRINT --attributes-only --archive '$NETWARE_PATH'" \ "$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \ - --attributes-only --backup "$NETWARE_PATH" + --attributes-only --archive "$NETWARE_PATH" run_cmd \ - "AFP Set File Information Clear Backup" \ - "./afp_set_file_info_smoke $COMMON_PRINT --attributes-only --clear-backup '$NETWARE_PATH'" \ + "AFP Set File Information Clear Archive" \ + "./afp_set_file_info_smoke $COMMON_PRINT --attributes-only --clear-archive '$NETWARE_PATH'" \ "$SCRIPT_DIR/afp_set_file_info_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" \ - --attributes-only --clear-backup "$NETWARE_PATH" + --attributes-only --clear-archive "$NETWARE_PATH" if command -v stat >/dev/null 2>&1; then run_cmd \