diff --git a/src/namspace.c b/src/namspace.c index b74444c..a6a0191 100644 --- a/src/namspace.c +++ b/src/namspace.c @@ -51,10 +51,6 @@ #define NW_PATH /* */ -static int ns06_fallback_obtain_info(int namespace, NW_HPATH *nwp, - int destnamspace, int searchattrib, - uint32 infomask, uint8 *responsedata); - typedef struct { int volume; /* Volume Number */ int has_wild; /* fn has wildcards */ @@ -911,48 +907,48 @@ static int build_base(int namespace, return(result); } +/* + * Build the DOS-visible short name for one namespace directory entry. + * + * This wrapper delegates all DOS short-name generation to dosmangle.c so + * that DOS namespace listings use the same naming rules as DOS path lookup + * and DOS wildcard matching. + */ static int build_dos_name(DIR_BASE_ENTRY *e, uint8 *fname, int size_fname) { - uint8 *ss=e->nwpath.fn; - int len=0; - int pf=0; - int is_ok=1; - int options=get_volume_options(e->nwpath.volume); - for (; *ss; ss++){ - if (*ss == '.') { - if (pf++) { /* no 2. point */ - is_ok=0; - break; - } - len=0; - } else { - ++len; - if ((pf && len > 3) || len > 8) { - is_ok=0; - break; - } - if (!(options & VOL_OPTION_IGNCASE)){ - if (options & VOL_OPTION_DOWNSHIFT){ /* only downshift chars */ - if (*ss >= 'A' && *ss <= 'Z') { - is_ok=0; - break; - } - } else { /* only upshift chars */ - if (*ss >= 'a' && *ss <= 'z') { - is_ok=0; - break; - } - } - } - } - } - if (is_ok) { - strmaxcpy(fname, e->nwpath.fn, size_fname-1); - up_fn(fname); - return(strlen(fname)); - } else { - return(sprintf(fname, "%ld.___", (long)e->nwpath.statb.st_ino)); - } + char dir_unix[1024]; + char *slash; + uint8 *unixname; + int options; + + if (!e || !fname || size_fname <= 0) + return 0; + + options = get_volume_options(e->nwpath.volume); + + /* + * Convert the full entry path to Unix form, then strip the last component. + * dosmangle.c uses the containing directory to check for alias collisions. + */ + unixname = alloc_nwpath2unix(&(e->nwpath), 2); + if (!unixname) + return 0; + + strncpy(dir_unix, (char *)unixname, sizeof(dir_unix) - 1); + dir_unix[sizeof(dir_unix) - 1] = '\0'; + xfree(unixname); + + slash = strrchr(dir_unix, '/'); + if (slash) + *slash = '\0'; + else + strcpy(dir_unix, "."); + + return dos83_build_name_in_dir(dir_unix, + e->nwpath.fn, + fname, + size_fname, + options); } #if 0 @@ -1035,7 +1031,7 @@ int nw_generate_dir_path(int namespace, DIR_BASE_ENTRY *dbe=dir_base[result]; U32_TO_32(dbe->basehandle, ns_dir_base); /* LOW - HIGH */ if (namespace != NAME_DOS) { - U32_TO_32(name_2_base(&(dbe->nwpath), NAME_DOS, 1), dos_dir_base); + U32_TO_32(dbe->basehandle, dos_dir_base); } else { U32_TO_32(dbe->basehandle, dos_dir_base); } @@ -1136,7 +1132,7 @@ static int build_dir_info(DIR_BASE_ENTRY *dbe, #if 0 U32_TO_32(dbe->basehandle, p); #else - U32_TO_32(name_2_base(nwpath, NAME_DOS, 1), p); + U32_TO_32(dbe->basehandle, p); #endif p +=4; U32_TO_32(nwpath->volume, p); @@ -1195,11 +1191,7 @@ int nw_optain_file_dir_info(int namespace, NW_HPATH *nwp, nwp_stat(&(dbe->nwpath), "nw_optain_file_dir_info"); result = build_dir_info(dbe, unixname, destnamspace, infomask, responsedata); xfree(unixname); - } else if ((result == -0xff || result == -0x9c) && - (namespace == NAME_DOS || namespace == NAME_OS2)) { - result = ns06_fallback_obtain_info(namespace, nwp, destnamspace, - searchattrib, infomask, responsedata); - } + } if (result < 0) { XDPRINTF((3, 0, "nw_optain_file_dir_info NOT OK result=-0x%x", -result)); } @@ -1526,7 +1518,49 @@ static int search_match(struct dirent *dirbuff, XDPRINTF((8,0,"search_match, Name='%s' dname='%s'", name, dname)); if (!inode_search) { if (namespace == NAME_DOS) { - flag = (*name != '.' && fn_dos_match_old(dname, entry, vol_options)); + char saved_dir[1024]; + char *slash; + uint8 dos_alias[DOS83_NAME_MAX + 1]; + + if (*name == '.') { + flag = 0; + } else { + /* + * Keep dname as the real name used later by get_add_new_entry(). + * Build the DOS-visible alias only for matching against the DOS + * namespace wildcard pattern. + */ + strncpy(saved_dir, (char *)ds->unixname, sizeof(saved_dir) - 1); + saved_dir[sizeof(saved_dir) - 1] = '\0'; + + slash = strrchr(saved_dir, '/'); + if (slash) + *slash = '\0'; + else + strcpy(saved_dir, "."); + + dos83_build_name_in_dir(saved_dir, + name, + dos_alias, + sizeof(dos_alias), + vol_options); + + XDPRINTF((2,0, + "NS search_match DOS alias entry='%s' raw='%s' alias='%s' namespace=%d", + entry, + name, + dos_alias, + namespace)); + + flag = fn_dos_match_old(dos_alias, entry, vol_options); + + XDPRINTF((2,0, + "NS search_match DOS alias result=%d entry='%s' raw='%s' alias='%s'", + flag, + entry, + name, + dos_alias)); + } } else if (namespace == NAME_OS2) { flag = (*name != '.' || (*(name+1) != '.' && *(name+1) != '\0' )) && fn_os2_match(dname, entry, vol_options); @@ -2034,71 +2068,6 @@ static int func_search_entry(DIR_BASE_ENTRY *dbe, int namespace, return(result); } - -typedef struct { - FUNC_SEARCH base; - int destnamspace; - uint32 infomask; - uint8 *responsedata; - int build_result; -} NS06_OBTAIN_INFO_SEARCH; - -static int ns06_obtain_info_cb(DIR_BASE_ENTRY *dbe, FUNC_SEARCH *fs) -{ - NS06_OBTAIN_INFO_SEARCH *ois = (NS06_OBTAIN_INFO_SEARCH *)fs; - char *unixname = alloc_nwpath2unix(&(dbe->nwpath), 2); - - nwp_stat(&(dbe->nwpath), "ns06_obtain_info_cb"); - ois->build_result = build_dir_info(dbe, unixname, - ois->destnamspace, - ois->infomask, - ois->responsedata); - xfree(unixname); - return ois->build_result; -} - -static int ns06_fallback_obtain_info(int namespace, NW_HPATH *nwp, - int destnamspace, int searchattrib, - uint32 infomask, uint8 *responsedata) -{ - uint8 search_entry[258]; - int parent_result; - NS06_OBTAIN_INFO_SEARCH ois; - - if (!nwp || nwp->components <= 0) - return -0xff; - - memset(&ois, 0, sizeof(ois)); - ois.base.ubuf = responsedata; - ois.destnamspace = destnamspace; - ois.infomask = infomask; - ois.responsedata = responsedata; - ois.build_result = -0xff; - - parent_result = build_base(namespace, nwp, nwp->pathes, 1, - search_entry, sizeof(search_entry)); - - XDPRINTF((2, 0, - "NS06 FALLBACK namespace=%d parent_result=0x%x search='%s'", - namespace, parent_result, search_entry)); - - if (parent_result > -1) { - DIR_BASE_ENTRY *parent_dbe = dir_base[parent_result]; - int search_res = func_search_entry(parent_dbe, namespace, - search_entry, - strlen((char *)search_entry), - searchattrib, - ns06_obtain_info_cb, - (FUNC_SEARCH *)&ois); - XDPRINTF((2, 0, - "NS06 FALLBACK SEARCH search_res=0x%x build_result=0x%x search='%s'", - search_res, ois.build_result, search_entry)); - if (search_res == 0 && ois.build_result > -1) - return ois.build_result; - } - return -0xff; -} - static int delete_file_dir(DIR_BASE_ENTRY *dbe, FUNC_SEARCH *fs) /* callbackroutine */ {