From 14d596d4d6418c43d08a7c32e9938860b84cf799 Mon Sep 17 00:00:00 2001 From: Mario Fetka Date: Wed, 20 May 2026 16:54:45 +0200 Subject: [PATCH] connect: preserve generated DOS aliases in legacy scan output Keep the generated DOS alias through the legacy scan response path instead of rebuilding it later from already-mangled data. --- src/connect.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/connect.c b/src/connect.c index 4be509c..6d5c2e7 100644 --- a/src/connect.c +++ b/src/connect.c @@ -66,6 +66,8 @@ static int act_umode_file=0; * first call in build_dir_name(). */ void mangle_dos_name(NW_VOL *vol, uint8 *unixname, uint8 *pp, int len); +static void build_dos_attr_name(int volume, uint8 *path, char *unixname, + struct stat *stb, uint8 *out, int out_len); typedef struct { @@ -1199,10 +1201,12 @@ time_t nw_2_un_time(uint8 *d, uint8 *t) static int get_file_attrib(NW_FILE_INFO *f, char *unixname, struct stat *stb, NW_PATH *nwpath) { + uint8 spath[14]; uint32 dwattrib; - strncpy((char*)f->name, (char*)nwpath->fn, sizeof(f->name)); - f->attrib[0]=0; /* d->name could be too long */ - up_fn(f->name); + build_dos_attr_name(nwpath->volume, nwpath->fn, unixname, stb, + spath, sizeof(spath)); + memset(f->name, 0, sizeof(f->name)); + strncpy((char*)f->name, (char*)spath, sizeof(f->name)-1); dwattrib = get_nw_attrib_dword(nwpath->volume, unixname, stb); U16_TO_16(dwattrib, f->attrib); @@ -1219,11 +1223,13 @@ static int get_file_attrib(NW_FILE_INFO *f, char *unixname, struct stat *stb, static int get_dir_attrib(NW_DIR_INFO *d, char *unixname, struct stat *stb, NW_PATH *nwpath) { + uint8 spath[14]; uint32 dwattrib; XDPRINTF((5,0, "get_dir_attrib of %s", conn_get_nwpath_name(nwpath))); - strncpy((char*)d->name, (char*)nwpath->fn, sizeof(d->name)); - d->attrib[0]=0; /* d->name could be too long */ - up_fn(d->name); + build_dos_attr_name(nwpath->volume, nwpath->fn, unixname, stb, + spath, sizeof(spath)); + memset(d->name, 0, sizeof(d->name)); + strncpy((char*)d->name, (char*)spath, sizeof(d->name)-1); dwattrib = get_nw_attrib_dword(nwpath->volume, unixname, stb); U16_TO_16(dwattrib, d->attrib); @@ -2462,10 +2468,23 @@ static void build_dos_attr_name(int volume, uint8 *path, char *unixname, char parent[300]; char *slash; uint8 *leaf = path; + int options = get_volume_options(volume); if (!out || out_len < 2) return; *out = '\0'; + /* + * Some old DOS scan paths already pass the synthesized 8.3 alias in + * `path`/nwpath->fn. If `unixname` was rebuilt from that alias, it no + * longer identifies the real long on-disk name; using it would collapse + * colliding long directories back to the same raw alias, e.g. LONG_DIR. + */ + if (path && *path && dos_is_83_name(path, options)) { + strmaxcpy(out, path, out_len-1); + up_fn(out); + return; + } + if (unixname && *unixname) { strmaxcpy(parent, unixname, sizeof(parent)-1); slash = strrchr(parent, '/'); @@ -2473,17 +2492,16 @@ static void build_dos_attr_name(int volume, uint8 *path, char *unixname, *slash = '\0'; if (*(slash+1)) leaf = (uint8*)(slash+1); if (!*parent) strcpy(parent, "/"); - build_dos_83_alias(get_volume_options(volume), (uint8*)parent, + build_dos_83_alias(options, (uint8*)parent, leaf, stb ? stb->st_ino : 0, out, out_len); return; } } - build_dos_83_alias(get_volume_options(volume), NULL, + build_dos_83_alias(options, NULL, leaf, stb ? stb->st_ino : 0, out, out_len); } - void get_dos_file_attrib(NW_DOS_FILE_INFO *f, struct stat *stb, int volume,