nwconn: align AFP attribute bits with WebSDK
All checks were successful
Source release / source-package (push) Successful in 46s
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:
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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'" \
|
||||
|
||||
Reference in New Issue
Block a user