tests: add AFP temporary directory handle entry-id smoke
This commit is contained in:
@@ -433,7 +433,7 @@ 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:
|
||||
`afp_temp_dir_handle_smoke` sends the WebSDK-documented NetWare AFP request. It can send either a path-backed request or `--entry-id-only`, where it first resolves the directory entry ID through AFP Get Entry ID From Path Name and then sends Alloc Temporary Directory Handle with `path_len=0`:
|
||||
|
||||
```text
|
||||
NCP 0x2222/35/11 AFP Alloc Temporary Directory Handle
|
||||
@@ -454,6 +454,7 @@ Useful smoke cases for a standard MARS-NWE `SYS` volume are:
|
||||
```sh
|
||||
./tests/afp/afp_temp_dir_handle_smoke -S MARS -U SUPERVISOR -P secret SYS:
|
||||
./tests/afp/afp_temp_dir_handle_smoke -S MARS -U SUPERVISOR -P secret SYS:PUBLIC
|
||||
./tests/afp/afp_temp_dir_handle_smoke --entry-id-only -S MARS -U SUPERVISOR -P secret SYS:PUBLIC
|
||||
./tests/afp/afp_temp_dir_handle_smoke -S MARS -U SUPERVISOR -P secret SYS:SYSTEM
|
||||
./tests/afp/afp_temp_dir_handle_smoke -S MARS -U SUPERVISOR -P secret SYS:BURST
|
||||
```
|
||||
@@ -472,7 +473,8 @@ 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:PUBLIC entry_id=0x00000000 dir_handle=2 rights=0xff
|
||||
AFP Alloc Temporary Dir Handle path=SYS:PUBLIC entry_id=0x00000004 dir_handle=2 rights=0xff entry-id-only
|
||||
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
|
||||
|
||||
@@ -461,6 +461,11 @@ run_cmd \
|
||||
"./afp_temp_dir_handle_smoke $COMMON_PRINT '$DIR_PATH'" \
|
||||
"$SCRIPT_DIR/afp_temp_dir_handle_smoke" -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$DIR_PATH"
|
||||
|
||||
run_cmd \
|
||||
"AFP Alloc Temporary Directory Handle by Entry ID" \
|
||||
"./afp_temp_dir_handle_smoke --entry-id-only $COMMON_PRINT '$DIR_PATH'" \
|
||||
"$SCRIPT_DIR/afp_temp_dir_handle_smoke" --entry-id-only -S "$SERVER" -U "$USER_NAME" -P "$PASSWORD" "$DIR_PATH"
|
||||
|
||||
if [ -d "$UNIX_DIR_PATH" ] || [ -d "$UNIX_DIR_PATH_DOS" ]; then
|
||||
run_optional_cmd \
|
||||
"Prepare AFP Create Directory cleanup" \
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
*
|
||||
* This uses ncpfs/libncp so the request travels through the same NCP path as a
|
||||
* normal Linux requester. The server-side AFP endpoint returns a temporary
|
||||
* NetWare directory handle and an effective-rights mask for a path-backed AFP
|
||||
* request.
|
||||
* NetWare directory handle and an effective-rights mask for either a
|
||||
* path-backed AFP request or an entry-id-only request.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
@@ -25,6 +25,7 @@
|
||||
#endif
|
||||
|
||||
#define AFP_ALLOC_TEMPORARY_DIR_HANDLE 0x0b
|
||||
#define AFP_GET_ENTRY_ID_FROM_PATH_NAME 0x0c
|
||||
#define NWE_INVALID_NAMESPACE 0xbf
|
||||
#define NWE_INVALID_PATH 0x9c
|
||||
#define AFP_TEMP_DH_NONE 0xff
|
||||
@@ -32,17 +33,19 @@
|
||||
static void usage(const char *prog)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: %s [--allow-invalid-namespace] [--allow-invalid-path] "
|
||||
"[--volume N] [--entry-id ID] [ncpfs options] PATH\n"
|
||||
"Usage: %s [--entry-id-only] [--allow-invalid-namespace] "
|
||||
"[--allow-invalid-path] [--volume N] [--entry-id ID] "
|
||||
"[ncpfs options] PATH\n"
|
||||
"\n"
|
||||
"ncpfs options are parsed by ncp_initialize(), for example:\n"
|
||||
" -S SERVER -U USER -P PASSWORD -n\n"
|
||||
"\n"
|
||||
"Examples:\n"
|
||||
" %s -S MARS -U SUPERVISOR -P secret SYS:PUBLIC\n"
|
||||
" %s --entry-id-only -S MARS -U SUPERVISOR -P secret SYS:PUBLIC\n"
|
||||
" %s --allow-invalid-namespace -S MARS -U SUPERVISOR -P secret SYS:PUBLIC\n"
|
||||
" %s --allow-invalid-path -S MARS -U SUPERVISOR -P secret SYS:NO_SUCH_PATH\n",
|
||||
prog, prog, prog, prog);
|
||||
prog, prog, prog, prog, prog);
|
||||
}
|
||||
|
||||
static int parse_u32(const char *text, uint32_t *value)
|
||||
@@ -66,6 +69,46 @@ static void cpu_to_be32(uint32_t v, uint8_t p[4])
|
||||
p[3] = (uint8_t)v;
|
||||
}
|
||||
|
||||
static uint32_t be32_to_cpu(const uint8_t p[4])
|
||||
{
|
||||
return ((uint32_t)p[0] << 24) |
|
||||
((uint32_t)p[1] << 16) |
|
||||
((uint32_t)p[2] << 8) |
|
||||
(uint32_t)p[3];
|
||||
}
|
||||
|
||||
static NWCCODE afp_get_entry_id_from_path(NWCONN_HANDLE conn, const char *path,
|
||||
uint32_t *entry_id)
|
||||
{
|
||||
NW_FRAGMENT reply;
|
||||
uint8_t request[1 + 1 + 255];
|
||||
uint8_t reply_buf[4];
|
||||
size_t path_len = strlen(path);
|
||||
NWCCODE err;
|
||||
|
||||
if (path_len > 255)
|
||||
return NWE_INVALID_PATH;
|
||||
|
||||
request[0] = 0; /* directory handle 0, raw VOL:path */
|
||||
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_PATH;
|
||||
|
||||
*entry_id = be32_to_cpu(reply_buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void deallocate_dir_handle(NWCONN_HANDLE conn, unsigned int dir_handle)
|
||||
{
|
||||
uint8_t rq[1];
|
||||
@@ -85,6 +128,7 @@ int main(int argc, char **argv)
|
||||
const char *path = NULL;
|
||||
int allow_invalid_namespace = 0;
|
||||
int allow_invalid_path = 0;
|
||||
int entry_id_only = 0;
|
||||
uint32_t volume_number = 0;
|
||||
uint32_t base_entry_id = 0;
|
||||
unsigned int allocated_dir_handle = AFP_TEMP_DH_NONE;
|
||||
@@ -109,6 +153,8 @@ int main(int argc, char **argv)
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (!strcmp(argv[i], "--allow-invalid-namespace")) {
|
||||
allow_invalid_namespace = 1;
|
||||
} else if (!strcmp(argv[i], "--entry-id-only")) {
|
||||
entry_id_only = 1;
|
||||
} else if (!strcmp(argv[i], "--allow-invalid-path")) {
|
||||
allow_invalid_path = 1;
|
||||
} else if (!strcmp(argv[i], "--volume")) {
|
||||
@@ -145,7 +191,23 @@ int main(int argc, char **argv)
|
||||
return 2;
|
||||
}
|
||||
|
||||
path_len = strlen(path);
|
||||
if (entry_id_only && !base_entry_id) {
|
||||
err = afp_get_entry_id_from_path(conn, path, &base_entry_id);
|
||||
if (err) {
|
||||
fprintf(stderr,
|
||||
"AFP Get Entry ID From Path Name failed before entry-id-only temporary handle allocation: completion=0x%02x (%u) path=%s\n",
|
||||
(unsigned int)err & 0xff, (unsigned int)err, path);
|
||||
ncp_close(conn);
|
||||
return 1;
|
||||
}
|
||||
if (!base_entry_id) {
|
||||
fprintf(stderr, "AFP Get Entry ID From Path Name returned zero for %s\n", path);
|
||||
ncp_close(conn);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
path_len = entry_id_only ? 0 : strlen(path);
|
||||
if (path_len > 255) {
|
||||
fprintf(stderr,
|
||||
"PATH is too long for AFP Alloc Temporary Directory Handle: %zu\n",
|
||||
@@ -157,7 +219,8 @@ int main(int argc, char **argv)
|
||||
request[0] = (uint8_t)volume_number;
|
||||
cpu_to_be32(base_entry_id, request + 1);
|
||||
request[5] = (uint8_t)path_len;
|
||||
memcpy(request + 6, path, path_len);
|
||||
if (path_len)
|
||||
memcpy(request + 6, path, path_len);
|
||||
|
||||
memset(reply_buf, 0, sizeof(reply_buf));
|
||||
reply.fragAddr.rw = reply_buf;
|
||||
@@ -199,8 +262,9 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
allocated_dir_handle = reply_buf[0];
|
||||
printf("AFP Alloc Temporary Dir Handle path=%s dir_handle=%u rights=0x%02x\n",
|
||||
path, allocated_dir_handle, (unsigned int)reply_buf[1]);
|
||||
printf("AFP Alloc Temporary Dir Handle path=%s entry_id=0x%08x dir_handle=%u rights=0x%02x%s\n",
|
||||
path, (unsigned int)base_entry_id, allocated_dir_handle,
|
||||
(unsigned int)reply_buf[1], entry_id_only ? " entry-id-only" : "");
|
||||
|
||||
deallocate_dir_handle(conn, allocated_dir_handle);
|
||||
ncp_close(conn);
|
||||
|
||||
Reference in New Issue
Block a user