tests: add AFP entry-id-relative name lookup smoke
All checks were successful
Source release / source-package (push) Successful in 45s

This commit is contained in:
Mario Fetka
2026-05-31 05:37:10 +00:00
parent 6230aa1d7c
commit a4104ece34
3 changed files with 88 additions and 12 deletions

View File

@@ -375,23 +375,29 @@ request:
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.
Use `--from-name` to select this subfunction. mars_nwe supports both the
path-backed smoke mode and the documented entry-id-relative form. The
path-backed form passes a raw `SYS:`-style path with base Entry ID 0. The
entry-id-relative form first resolves a directory base with
`AFP Get Entry ID From Path Name`, then sends the leaf name with that base
Entry ID and no `VOL:` prefix.
Useful smoke cases for a standard MARS-NWE `SYS` volume are:
```sh
./tests/afp/afp_entry_id_smoke --from-name -S MARS -U SUPERVISOR -P secret SYS:
./tests/afp/afp_entry_id_smoke --from-name -S MARS -U SUPERVISOR -P secret SYS:PUBLIC
./tests/afp/afp_entry_id_smoke --from-name --base-path SYS:PUBLIC -S MARS -U SUPERVISOR -P secret pmdflts.ini
./tests/afp/afp_entry_id_smoke --from-name -S MARS -U SUPERVISOR -P secret SYS:SYSTEM
./tests/afp/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.
probe. Path-backed requests use the normal raw `VOL:PATH` resolver.
Entry-id-relative requests use the directory Entry ID only as a base directory,
resolve that base through the mars_nwe namespace/basehandle path, and then feed
the composed `VOL:BASE/NAME` path back into the normal mars_nwe resolver.
Regular file Entry IDs are not treated as directory bases.
### AFP Get Entry ID From NetWare Handle

View File

@@ -28,13 +28,16 @@
#define AFP_GET_ENTRY_ID_FROM_PATH_NAME 0x0c
#define NWE_INVALID_NAMESPACE 0xbf
#define NWE_INVALID_PATH 0x9c
#ifndef NWE_INVALID_NCP_PACKET_LENGTH
#define NWE_INVALID_NCP_PACKET_LENGTH 0x7e
#endif
#define AFP_TEMP_DH_NONE 0xff
static void usage(const char *prog)
{
fprintf(stderr,
"Usage: %s [--allow-invalid-namespace] [--allow-invalid-path] "
"[--from-name] [--from-handle] [--volume N] [--entry-id ID] "
"[--from-name] [--from-handle] [--volume N] [--entry-id ID] [--base-path PATH] "
"[--dir-handle N] [--alloc-handle] [--raw-path] [ncpfs options] PATH\n"
"\n"
"ncpfs options are parsed by ncp_initialize(), for example:\n"
@@ -43,12 +46,13 @@ static void usage(const char *prog)
"Examples:\n"
" %s -S MARS -U SUPERVISOR -P secret SYS:PUBLIC\n"
" %s --from-name -S MARS -U SUPERVISOR -P secret SYS:PUBLIC\n"
" %s --from-name --base-path SYS:PUBLIC -S MARS -U SUPERVISOR -P secret pmdflts.ini\n"
" %s --from-handle -S MARS -U SUPERVISOR -P secret SYS:PUBLIC/pmdflts.ini\n"
" %s --dir-handle 2 -S MARS -U SUPERVISOR -P secret PUBLIC\n"
" %s --alloc-handle -S MARS -U SUPERVISOR -P secret SYS:PUBLIC\n"
" %s --allow-invalid-namespace -S MARS SYS:PUBLIC\n"
" %s --allow-invalid-path -S MARS SYS:NO_SUCH_PATH\n",
prog, prog, prog, prog, prog, prog, prog, prog);
prog, prog, prog, prog, prog, prog, prog, prog, prog);
}
static int parse_u8(const char *text, unsigned int *value)
@@ -182,6 +186,38 @@ static void deallocate_dir_handle(NWCONN_HANDLE conn, unsigned int dir_handle)
(void)NWRequestSimple(conn, NCPC_SFN(0x16, 0x14), rq, sizeof(rq), NULL);
}
static NWCCODE afp_lookup_entry_id_from_path(NWCONN_HANDLE conn, const char *path,
uint32_t *entry_id)
{
uint8_t request[2 + 255];
uint8_t reply_buf[4];
NW_FRAGMENT reply;
size_t path_len = strlen(path);
NWCCODE err;
if (path_len > 255)
return NWE_INVALID_PATH;
request[0] = 0;
request[1] = (uint8_t)path_len;
memcpy(request + 2, path, path_len);
memset(reply_buf, 0, sizeof(reply_buf));
reply.fragAddr.rw = reply_buf;
reply.fragSize = sizeof(reply_buf);
err = NWRequestSimple(conn,
NCPC_SFN(0x23, AFP_GET_ENTRY_ID_FROM_PATH_NAME),
request, 2 + path_len, &reply);
if (err)
return err;
if (reply.fragSize < 4)
return NWE_INVALID_NCP_PACKET_LENGTH;
*entry_id = be32_to_cpu(reply_buf);
return 0;
}
int main(int argc, char **argv)
{
NWCONN_HANDLE conn;
@@ -189,6 +225,7 @@ int main(int argc, char **argv)
long init_err = 0;
const char *path = NULL;
const char *request_path = NULL;
const char *base_path = NULL;
unsigned int dir_handle = 0;
unsigned int allocated_dir_handle = AFP_TEMP_DH_NONE;
int allow_invalid_namespace = 0;
@@ -255,6 +292,17 @@ int main(int argc, char **argv)
ncp_close(conn);
return 2;
}
} else if (!strcmp(argv[i], "--base-path")) {
if (++i >= argc) {
fprintf(stderr, "missing --base-path value\n");
ncp_close(conn);
return 2;
}
base_path = argv[i];
from_name = 1;
from_handle = 0;
raw_path = 1;
alloc_handle = 0;
} else if (!strcmp(argv[i], "--raw-path")) {
raw_path = 1;
alloc_handle = 0;
@@ -311,6 +359,18 @@ int main(int argc, char **argv)
allocated_dir_handle = dir_handle;
}
if (base_path) {
err = afp_lookup_entry_id_from_path(conn, base_path, &base_entry_id);
if (err) {
fprintf(stderr,
"AFP base-path lookup failed before From Name: completion=0x%02x (%u) base_path=%s\n",
(unsigned int)err & 0xff, (unsigned int)err, base_path);
deallocate_dir_handle(conn, allocated_dir_handle);
ncp_close(conn);
return 1;
}
}
if (from_handle) {
memset(&opened_file, 0, sizeof(opened_file));
err = ncp_open_file(conn, 0, request_path, 0, AR_READ_ONLY, &opened_file);
@@ -413,10 +473,11 @@ int main(int argc, char **argv)
(unsigned int)be32_to_cpu(reply_buf + 1),
(unsigned int)reply_buf[5]);
} else {
printf("AFP Entry ID path=%s request_path=%s dir_handle=%u entry_id=0x%08x (%u)\n",
path, request_path, dir_handle,
printf("AFP Entry ID path=%s request_path=%s dir_handle=%u base_entry_id=0x%08x entry_id=0x%08x (%u)%s\n",
path, request_path, dir_handle, (unsigned int)base_entry_id,
(unsigned int)be32_to_cpu(reply_buf),
(unsigned int)be32_to_cpu(reply_buf));
(unsigned int)be32_to_cpu(reply_buf),
base_path ? " entry-id-relative" : "");
}
if (opened_file_valid)

View File

@@ -176,8 +176,12 @@ case "$RENAME_FILE_NAME" in
esac
DIR_PATH=$NETWARE_PATH
NETWARE_LEAF=$NETWARE_PATH
case "$NETWARE_PATH" in
*/*) DIR_PATH=${NETWARE_PATH%/*} ;;
*/*)
DIR_PATH=${NETWARE_PATH%/*}
NETWARE_LEAF=${NETWARE_PATH##*/}
;;
esac
CREATE_DIR_PATH="$DIR_PATH/$CREATE_DIR_NAME"
CREATE_DIR20_PATH="$DIR_PATH/${CREATE_DIR_NAME}2"
@@ -441,6 +445,11 @@ run_cmd \
"./afp_entry_id_smoke --from-handle $COMMON_PRINT '$NETWARE_PATH'" \
"$SCRIPT_DIR/afp_entry_id_smoke" --from-handle -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$NETWARE_PATH"
run_cmd \
"AFP Entry ID From Name relative to Entry ID" \
"./afp_entry_id_smoke --from-name --base-path '$DIR_PATH' $COMMON_PRINT '$NETWARE_LEAF'" \
"$SCRIPT_DIR/afp_entry_id_smoke" --from-name --base-path "$DIR_PATH" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$NETWARE_LEAF"
run_cmd \
"AFP 2.0 Get File Information" \
"./afp_file_info_smoke $COMMON_PRINT '$NETWARE_PATH'" \