connect: cache real directory entries for DOS alias output

Remember the real Unix directory entry found during legacy scans so
the final DOS name can be generated from the original parent/name pair.
This commit is contained in:
Mario Fetka
2026-05-20 17:13:00 +02:00
parent 1984aa4d28
commit 1a5b89a9fd
2 changed files with 39 additions and 13 deletions

View File

@@ -116,6 +116,28 @@ static DIR_HANDLE dir_handles[MAX_DIRHANDLES];
static int anz_dirhandles=0;
/* Last real directory entry found by the old DOS scan code.
* Some callers rebuild unixname later from the synthetic DOS alias; keep the
* real parent/name pair so the final attribute formatter can still generate
* a collision-aware 8.3 alias for display.
*/
static int last_dos_alias_volume = -1;
static ino_t last_dos_alias_inode = 0;
static uint8 last_dos_alias_parent[300];
static uint8 last_dos_alias_real[256];
static void remember_dos_alias_source(int volume, uint8 *parent, uint8 *real,
ino_t inode)
{
last_dos_alias_volume = volume;
last_dos_alias_inode = inode;
strmaxcpy(last_dos_alias_parent, parent ? (char*)parent : "",
sizeof(last_dos_alias_parent)-1);
strmaxcpy(last_dos_alias_real, real ? (char*)real : "",
sizeof(last_dos_alias_real)-1);
}
static char *build_unix_name(NW_PATH *nwpath, int modus)
/*
* returns complete UNIX path
@@ -621,6 +643,9 @@ static int func_search_entry(NW_PATH *nwpath, int attrib,
okflag = ( ( ( (fs->statb.st_mode & S_IFMT) == S_IFDIR) && (attrib & 0x10))
|| ( ( (fs->statb.st_mode & S_IFMT) != S_IFDIR) && !(attrib & 0x10)));
if (okflag){
*kpath = '';
remember_dos_alias_source(volume, (uint8*)xkpath, name,
fs->statb.st_ino);
xstrcpy(nwpath->fn, (char*)dosalias);
XDPRINTF((5,0,"FOUND=:%s: attrib=0x%x", nwpath->fn, fs->statb.st_mode));
result = (*fs_func)(nwpath, fs);
@@ -696,8 +721,6 @@ static int get_dir_entry(NW_PATH *nwpath,
*kpath = '\0';
build_dos_83_alias(soptions, (uint8*)xkpath, name,
dirbuff->d_ino, dosalias, sizeof(dosalias));
XDPRINTF((1,0,"DOSSCAN get_dir_entry parent='%s' real='%s' alias='%s' entry='%s'",
xkpath, name, dosalias, entry));
okflag = ((name[0] != '.' &&
( (!strcmp((char*)dosalias, (char*)entry))
|| fn_dos_match(dosalias, entry, soptions)))) ? 0 : -0xff;
@@ -714,6 +737,9 @@ static int get_dir_entry(NW_PATH *nwpath,
if (soptions & VOL_OPTION_IS_PIPE) {
statb->st_size = 0x70000000|(statb->st_mtime&0xfffffff);
}
*kpath = '';
remember_dos_alias_source(volume, (uint8*)xkpath, name,
statb->st_ino);
xstrcpy(nwpath->fn, (char*)dosalias);
XDPRINTF((5,0,"FOUND=:%s: attrib=0x%x", nwpath->fn, statb->st_mode));
break; /* ready */
@@ -803,8 +829,6 @@ static int get_dh_entry(DIR_HANDLE *dh,
unix2doscharset(dname);
build_dos_83_alias(dh->vol_options, (uint8*)dh->unixname, name,
dirbuff->d_ino, dosalias, sizeof(dosalias));
XDPRINTF((1,0,"DOSSCAN get_dh_entry parent='%s' real='%s' alias='%s' entry='%s'",
dh->unixname, name, dosalias, entry));
okflag = (name[0] != '.' &&
( (!strcmp((char*)dosalias, (char*)entry))
|| fn_dos_match(dosalias, entry, dh->vol_options)));
@@ -827,6 +851,9 @@ static int get_dh_entry(DIR_HANDLE *dh,
if (okflag){
if (unixname)
strmaxcpy(unixname, dh->unixname, size_unixname-1);
*(dh->kpath) = '';
remember_dos_alias_source(dh->volume, (uint8*)dh->unixname,
name, statb->st_ino);
strmaxcpy((char*)search, (char*)dosalias, size_search-1);
break; /* ready */
}
@@ -1232,8 +1259,6 @@ static int get_dir_attrib(NW_DIR_INFO *d, char *unixname, struct stat *stb,
XDPRINTF((5,0, "get_dir_attrib of %s", conn_get_nwpath_name(nwpath)));
build_dos_attr_name(nwpath->volume, nwpath->fn, unixname, stb,
spath, sizeof(spath));
XDPRINTF((1,0,"DOSATTR DIR path='%s' unix='%s' out='%s'",
nwpath->fn, unixname ? unixname : "", spath));
memset(d->name, 0, sizeof(d->name));
strncpy((char*)d->name, (char*)spath, sizeof(d->name)-1);
@@ -2479,6 +2504,14 @@ static void build_dos_attr_name(int volume, uint8 *path, char *unixname,
if (!out || out_len < 2) return;
*out = '\0';
if (stb && volume == last_dos_alias_volume
&& stb->st_ino == last_dos_alias_inode
&& last_dos_alias_parent[0] && last_dos_alias_real[0]) {
build_dos_83_alias(options, last_dos_alias_parent,
last_dos_alias_real, stb->st_ino, out, out_len);
return;
}
/*
* 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

View File

@@ -203,13 +203,6 @@ int build_dos_83_alias(int options, uint8 *parent_unix,
}
up_fn(alias);
XDPRINTF((1, 0,
"DOSALIAS parent='%s' real='%s' raw='%s' collisions=%d alias='%s'",
(parent_unix && *parent_unix) ? (char*)parent_unix : "",
real_name ? (char*)real_name : "",
raw,
collisions,
alias));
return(strlen((char*)alias));
}