fist implementation NCP23/F4 / F3
All checks were successful
Source release / source-package (push) Successful in 38s

This commit is contained in:
Mario Fetka
2026-05-25 15:48:45 +02:00
parent 6064e40dcb
commit d9f7d226b9
5 changed files with 143 additions and 3 deletions

View File

@@ -2331,6 +2331,45 @@ int nw_set_dir_handle(int targetdir, int dir_handle,
return(inode); /* invalid PATH */
}
int conn_map_path_to_dir_entry(int dirhandle, uint8 *data, int len,
uint8 *volume_out, uint8 *dirnum_out)
/*
* NCP23/F4 Convert Path to Dir Entry helper.
* Returns 0 or a negative mars_nwe/NCP error.
* Reply fields are volume byte and DOS namespace directory number (LO-HI).
*/
{
char unixname[512];
struct stat stbuff;
int volume = conn_get_kpl_unxname(unixname, sizeof(unixname),
dirhandle, data, len);
if (volume < 0) return(volume);
if (s_stat(unixname, &stbuff, NULL)) return(-0x9c);
if (!S_ISDIR(stbuff.st_mode)) return(-0x9c);
{
DEV_NAMESPACE_MAP dnm;
uint32 dirnum;
dnm.dev = stbuff.st_dev;
dnm.namespace = NAME_DOS;
dirnum = nw_vol_inode_to_handle(volume, stbuff.st_ino, &dnm);
if (!dirnum) return(-0x9b);
if (volume_out) *volume_out = (uint8)volume;
if (dirnum_out) U32_TO_32(dirnum, dirnum_out);
XDPRINTF((5,0,
"NCP23/F4 helper: dh=%d pathlen=%d unix=`%s` vol=%d dirnum=0x%lx",
dirhandle, len, unixname, volume, (unsigned long)dirnum));
}
return(0);
}
int nw_get_directory_path(int dir_handle, uint8 *name, int size_name)
{
int result = -0x9b;

View File

@@ -2908,6 +2908,63 @@ int fill_namespace_buffer(int volume, uint8 *rdata)
} else return(-0x98);
}
int map_directory_number_to_path(int volume, uint32 dirnum,
int namspace, uint8 *rdata, int size_rdata)
/*
* NCP23/F3 Map Directory Number to Path.
* Reply is a sequence of length-preceded path components, without volume.
*/
{
int result = find_base_entry(volume, dirnum);
XDPRINTF((5,0,
"NCP23/F3 helper: vol=%d dirnum=0x%lx namespace=%d",
volume, (unsigned long)dirnum, namspace));
if (result > -1) {
DIR_BASE_ENTRY *e = dir_base[result];
char path[512];
char *pp;
uint8 *out = rdata;
int left = size_rdata;
if (!rdata || size_rdata < 1) return(-0xff);
strmaxcpy((uint8*)path, e->nwpath.path, sizeof(path)-1);
if (namspace == NAME_DOS) up_fn((uint8*)path);
pp = path;
while (*pp == '/' || *pp == '\\') pp++;
if (!*pp)
return(0);
while (*pp) {
char *next = pp;
int len;
while (*next && *next != '/' && *next != '\\') next++;
len = next - pp;
if (len > 255 || left < len + 1) return(-0xff);
*out++ = (uint8)len;
memcpy(out, pp, len);
out += len;
left -= len + 1;
while (*next == '/' || *next == '\\') next++;
pp = next;
}
XDPRINTF((5,0,
"NCP23/F3 helper: path=`%s` reply_len=%d",
e->nwpath.path, (int)(out - rdata)));
return((int)(out - rdata));
}
return(result);
}
int get_namespace_dir_entry(int volume, uint32 basehandle,
int namspace, uint8 *rdata)
{

View File

@@ -1559,19 +1559,57 @@ static int handle_ncp_serv(void)
}
break;
case 0xf3: { /* Map Direktory Number TO PATH */
case 0xf3: { /* Map Directory Number TO PATH */
int payload_len = requestlen - 3;
int result;
if (payload_len < 0) payload_len = 0;
ncp23_debug_dump("NCP23/F3 Map Directory Number TO PATH", rdata, payload_len);
completition = 0xff;
/*
* Request: volume byte, directory number dword LO-HI, namespace byte.
* Reply: length-preceded path components, no volume component.
*/
if (payload_len >= 6) {
int volume = (int)rdata[0];
uint32 dirnum = GET_32(rdata+1);
int namspace = (int)rdata[5];
result = map_directory_number_to_path(volume, dirnum, namspace,
responsedata,
sizeof(IPX_DATA) - sizeof(NCPRESPONSE));
if (result > -1) data_len = result;
else completition = (uint8)(-result);
} else {
completition = 0x9c;
}
}
break;
case 0xf4: { /* Map PATH TO Dir Entry */
int payload_len = requestlen - 3;
int result;
if (payload_len < 0) payload_len = 0;
ncp23_debug_dump("NCP23/F4 Map PATH TO Dir Entry", rdata, payload_len);
completition = 0xff;
/*
* Request: dir handle byte, path length byte, path bytes.
* Reply: volume byte, directory number dword LO-HI.
*/
if (payload_len >= 2 && payload_len >= 2 + (int)rdata[1]) {
struct XDATA {
uint8 volume;
uint8 dirnum[4];
} *xdata = (struct XDATA*)responsedata;
result = conn_map_path_to_dir_entry((int)rdata[0],
rdata+2, (int)rdata[1],
&(xdata->volume),
xdata->dirnum);
if (result) completition = (uint8)(-result);
else data_len = sizeof(struct XDATA);
} else {
completition = 0x9c;
}
}
break;