nwconn: implement AFP delete through NetWare remove paths

This commit is contained in:
Test
2026-05-30 19:52:53 +00:00
committed by Mario Fetka
parent 3b3a378a22
commit 4183a63689

View File

@@ -1143,6 +1143,88 @@ static int afp_create_directory(uint8 *afp_req, int afp_len,
}
static int afp_delete_object(uint8 *afp_req, int afp_len,
const char *call_name)
/*
* WebSDK / nwafp.h call 0x03 removes an AFP file or directory. Keep the
* delete operation on existing mars_nwe paths: resolve volume/base-id/path to
* the normal NetWare path string, then call nw_mk_rd_dir(..., mode=0) for
* directories or nw_delete_files() for files. This avoids a direct
* unlink(2)/rmdir(2) AFP side path while giving the smoke suite a server-side
* cleanup path for AFP-created objects.
*/
{
uint8 volume_number;
uint32 base_entry_id;
int path_len;
uint8 delete_path[512];
char unixname[PATH_MAX];
int volume;
int result;
struct stat stbuff;
if (afp_len < 7) {
XDPRINTF((2,0, "%s rejected: short request len=%d",
call_name, afp_len));
return(-0x7e);
}
volume_number = afp_req[1];
base_entry_id = GET_BE32(afp_req + 2);
path_len = (int)afp_req[6];
if (path_len < 0 || afp_len < 7 + path_len) {
XDPRINTF((2,0, "%s rejected: boundary check len=%d path_len=%d",
call_name, afp_len, path_len));
return(-0x7e);
}
if (!path_len) {
XDPRINTF((2,0, "%s rejected: empty path vol=%d base=0x%08x",
call_name, (int)volume_number, base_entry_id));
return(-0x9c);
}
result = afp_build_base_relative_path((int)volume_number, base_entry_id,
afp_req + 7, path_len,
delete_path, sizeof(delete_path));
if (result < 0) {
XDPRINTF((2,0, "%s path build failed: vol=%d base=0x%08x path='%s' result=-0x%x",
call_name, (int)volume_number, base_entry_id,
visable_data(afp_req + 7, path_len), -result));
return(result);
}
volume = conn_get_kpl_unxname(unixname, sizeof(unixname), 0,
delete_path, strlen((char *)delete_path));
if (volume < 0) return(volume);
if (stat(unixname, &stbuff)) {
XDPRINTF((2,0, "%s stat failed: vol=%d base=0x%08x path='%s' mars_path='%s' unix='%s' errno=%d",
call_name, (int)volume_number, base_entry_id,
visable_data(afp_req + 7, path_len), delete_path, unixname,
errno));
return(-0x9c);
}
if (S_ISDIR(stbuff.st_mode)) {
result = nw_mk_rd_dir(0, delete_path, strlen((char *)delete_path), 0);
} else {
result = nw_delete_files(0, 0, delete_path, strlen((char *)delete_path));
}
if (result < 0) {
XDPRINTF((2,0, "%s delete failed: vol=%d base=0x%08x path='%s' mars_path='%s' unix='%s' result=-0x%x",
call_name, (int)volume_number, base_entry_id,
visable_data(afp_req + 7, path_len), delete_path, unixname,
-result));
return(result);
}
XDPRINTF((3,0, "%s: request_vol=%d resolved_vol=%d base=0x%08x path='%s' directory=%d",
call_name, (int)volume_number, volume, base_entry_id,
visable_data(afp_req + 7, path_len), S_ISDIR(stbuff.st_mode) ? 1 : 0));
return(0);
}
static int afp_get_entry_id_from_path_name(uint8 *afp_req, int afp_len,
uint8 *response)
{
@@ -4189,6 +4271,11 @@ static int handle_ncp_serv(void)
afp_call_name(ufunc));
if (result > -1) data_len = result;
else completition = (uint8)-result;
} else if (ufunc == 0x03) {
int result = afp_delete_object(afp_req,
afp_len, afp_call_name(ufunc));
if (result > -1) data_len = result;
else completition = (uint8)-result;
} else if (ufunc == 0x04) {
int result = afp_get_entry_id_from_name(afp_req,
afp_len, responsedata);