From b768c921c8a05a099df984ad12fb131ac358beca Mon Sep 17 00:00:00 2001 From: OpenAI Date: Sat, 30 May 2026 14:39:57 +0000 Subject: [PATCH] nwconn: return DOS namespace names for AFP entry ids Route AFP Get DOS Name From Entry ID through the existing mars_nwe DOS namespace alias helper instead of returning raw Unix directory entry names from the reverse lookup walk. WebSDK semantics require this subfunction to return a DOSPathString. The current AFP entry ids are mars_nwe/libatalk metadata ids rather than namspace.c base handles, so the lookup still has to walk the volume tree, but each path component is now formatted with namedos.c build_dos_83_alias(). This keeps the Apple-facing adapter aligned with the existing DOS namespace rules used by normal NetWare clients. Update the Linux smoke helper's default expectation for raw VOL:PATH smoke inputs to compare against the DOS 8.3 uppercase form. Explicit --expect remains available for callers that want to validate a specific alias. Tests: git diff --check; gcc -Iinclude -I/mnt/data/stubs -fsyntax-only tests/linux/afp_dos_name_smoke.c --- src/nwconn.c | 31 +++++++++++++++++++++++++++++-- tests/linux/afp_dos_name_smoke.c | 20 ++++++++++++++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/nwconn.c b/src/nwconn.c index 3691d62..c05be94 100644 --- a/src/nwconn.c +++ b/src/nwconn.c @@ -50,6 +50,7 @@ #include "trustee.h" #include "nwatalk.h" #include "nwattrib.h" +#include "namedos.h" int act_pid = 0; @@ -900,6 +901,31 @@ static int afp_path_join(char *dst, int dst_len, const char *base, return(0); } +static int afp_dos_path_join(int volume, char *dst, int dst_len, + const char *base, const char *parent_unix, + const char *real_name, ino_t inode) +/* + * Build the documented DOS namespace path component by reusing namedos.c. + * + * AFP 0x12 returns a DOSPathString, not the real Unix directory entry name. + * The reverse lookup still walks the Unix volume tree because current AFP entry + * IDs are mars_nwe/libatalk metadata IDs, but the path returned to the client + * must be the DOS namespace alias that mars_nwe already uses elsewhere. + */ +{ + uint8 alias[14]; + + if (volume < 0 || volume >= used_nw_volumes) return(-1); + if (!real_name || !*real_name) return(-1); + + if (!build_dos_83_alias(nw_volumes[volume].options, + (uint8 *)parent_unix, (uint8 *)real_name, inode, + alias, sizeof(alias))) + return(-1); + + return(afp_path_join(dst, dst_len, base, (char *)alias)); +} + static int afp_find_dos_name_from_entry_id_rec(int volume, const char *unix_dir, const char *rel_dir, @@ -933,10 +959,11 @@ static int afp_find_dos_name_from_entry_id_rec(int volume, continue; if (afp_path_join(unix_child, sizeof(unix_child), unix_dir, de->d_name)) continue; - if (afp_path_join(rel_child, sizeof(rel_child), rel_dir, de->d_name)) - continue; if (lstat(unix_child, &stb)) continue; + if (afp_dos_path_join(volume, rel_child, sizeof(rel_child), rel_dir, + unix_dir, de->d_name, stb.st_ino)) + continue; if (!nwatalk_get_entry_id(unix_child, &entry_id) && entry_id == search->target_entry_id) { diff --git a/tests/linux/afp_dos_name_smoke.c b/tests/linux/afp_dos_name_smoke.c index 5adaa28..35ee0c5 100644 --- a/tests/linux/afp_dos_name_smoke.c +++ b/tests/linux/afp_dos_name_smoke.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -77,6 +78,18 @@ static const char *path_without_volume(const char *path) return path; } +static void default_dos_expectation(const char *path, char *out, size_t out_len) +{ + const char *src = path_without_volume(path); + size_t i; + + if (!out || !out_len) + return; + for (i = 0; i + 1 < out_len && src[i]; i++) + out[i] = (char)toupper((unsigned char)src[i]); + out[i] = '\0'; +} + static NWCCODE get_entry_id_for_path(NWCONN_HANDLE conn, const char *path, uint32_t *entry_id) { @@ -118,6 +131,7 @@ int main(int argc, char **argv) long init_err = 0; const char *path = NULL; const char *expect = NULL; + char default_expect[256]; int allow_invalid_namespace = 0; int allow_invalid_path = 0; uint32_t volume_number = 0; @@ -243,8 +257,10 @@ int main(int argc, char **argv) memcpy(dos_path, reply_buf + 1, reply_buf[0]); dos_path[reply_buf[0]] = '\0'; - if (!expect && path) - expect = path_without_volume(path); + if (!expect && path) { + default_dos_expectation(path, default_expect, sizeof(default_expect)); + expect = default_expect; + } if (expect && strcmp(expect, dos_path)) { fprintf(stderr, "AFP Get DOS Name From Entry ID verify mismatch: volume=%u entry_id=0x%08x got=%s expected=%s\n",