ncp: inline salvage endpoint parsing in cases
All checks were successful
Source release / source-package (push) Successful in 1m0s

This commit is contained in:
test
2026-05-31 19:48:59 +00:00
committed by Mario Fetka
parent 54181247b1
commit 396dd8e66f
3 changed files with 259 additions and 260 deletions

View File

@@ -107,12 +107,11 @@ typedef struct {
extern int handle_func_0x57(uint8 *p, int request_len,
uint8 *responsedata, int task);
extern int handle_func_salvage_scan(uint8 *p, int request_len,
uint8 *responsedata, int task);
extern int handle_func_salvage_recover(uint8 *p, int request_len,
uint8 *responsedata, int task);
extern int handle_func_salvage_purge(uint8 *p, int request_len,
uint8 *responsedata, int task);
extern int nsp_salvage_scan_short_handle(int dir_handle, uint32 sequence,
uint8 *responsedata);
extern int nsp_salvage_recover_short_handle(int dir_handle, uint32 sequence,
int task);
extern int nsp_salvage_purge_short_handle(int dir_handle, uint32 sequence);
extern int handle_func_0x56(uint8 *p, uint8 *responsedata, int task);
extern int fill_namespace_buffer(int volume, uint8 *rdata);

View File

@@ -2790,104 +2790,6 @@ static int nsp_salvage_dbe_from_short_handle(int dir_handle,
static int nsp_salvage_build_old_info(const struct nwsalvage_scan_result *scan,
uint8 *p);
int handle_func_salvage_scan(uint8 *q, int request_len,
uint8 *responsedata, int task)
{
int namespace;
uint32 infomask;
uint32 scan_sequence;
NW_HPATH *nwpathstruct;
int result;
DIR_BASE_ENTRY *dbe;
struct nwsalvage_scan_result scan;
uint8 *p = responsedata;
(void)task;
if (q && q[0] == 0x1b) { /* old 22/27 Scan Salvageable Files */
int dir_handle;
uint32 sequence;
if (request_len < 6)
return(-0xfb);
dir_handle = (int)q[1];
sequence = GET_32(q + 2);
result = nsp_salvage_dbe_from_short_handle(dir_handle, &dbe);
if (result < 0)
return(result);
result = nsp_salvage_scan_by_dbe(dbe, sequence, &scan);
if (result)
return(result);
result = nsp_salvage_build_old_info(&scan, responsedata);
XDPRINTF((3, 0,
"INFO SALVAGE 22/27 DONE fn=0x16 sub=0x1b dh=0x%02x seq=0x%08lx next=0x%08lx name=\"%s\"",
dir_handle, (unsigned long)sequence,
(unsigned long)scan.scan_sequence, scan.metadata.original_name));
return(result);
}
if (!q || request_len < 18 || q[0] != 0x10)
return(-0xfb);
namespace = (int)q[1];
infomask = GET_32(q + 3);
scan_sequence = GET_32(q + 7);
nwpathstruct = (NW_HPATH *)(q + 11);
{
uint8 *pp = nwpathstruct->pathes;
uint8 *end = q + request_len;
int k;
for (k = 0; k < nwpathstruct->components; k++) {
int len;
if (pp >= end)
return(-0xfb);
len = (int)*pp++;
if (len > (int)(end - pp))
return(-0xfb);
pp += len;
}
}
result = build_base(namespace, nwpathstruct, nwpathstruct->pathes,
0, NULL, 0);
if (result < 0)
return(result);
dbe = dir_base[result];
nwp_stat(&(dbe->nwpath), "nsp_handle_salvage_scan");
if (!S_ISDIR(dbe->nwpath.statb.st_mode))
return(-0x9c);
result = nsp_salvage_scan_by_dbe(dbe, scan_sequence, &scan);
if (result)
return(result);
U32_TO_32((uint32)scan.scan_sequence, p); p += 4;
un_time_2_nw((time_t)scan.metadata.deleted_at, p, 0); p += 2;
un_date_2_nw((time_t)scan.metadata.deleted_at, p, 0); p += 2;
U32_TO_BE32(nsp_salvage_deletor_id(scan.metadata.deleted_by), p); p += 4;
U32_TO_32((uint32)scan.scan_volume, p); p += 4;
U32_TO_32((uint32)scan.scan_directory_base, p); p += 4;
result = nsp_salvage_build_info(&scan.metadata, namespace, infomask, p);
if (result < 0)
return(result);
result += (int)(p - responsedata);
XDPRINTF((3, 0, "NCP 87/16 salvage scan seq=0x%lx next=0x%lx name='%s' result=%d",
(unsigned long)scan_sequence, scan.scan_sequence,
scan.metadata.original_name, result));
return(result);
}
static void nsp_salvage_datetime_lh(time_t t, uint8 *p)
{
uint8 b[2];
@@ -3041,166 +2943,69 @@ static int nsp_salvage_build_old_info(const struct nwsalvage_scan_result *scan,
return(130);
}
int handle_func_salvage_recover(uint8 *q, int request_len,
uint8 *responsedata, int task)
int nsp_salvage_scan_short_handle(int dir_handle, uint32 sequence,
uint8 *responsedata)
{
int namespace;
uint32 scan_sequence;
uint32 volume;
uint32 directory_base;
int result;
DIR_BASE_ENTRY *dbe;
struct nwsalvage_scan_result scan;
(void)responsedata;
if (q && q[0] == 0x1c) { /* old 22/28 Recover Salvageable File */
int dir_handle;
uint32 sequence;
int file_len;
int new_len;
DIR_BASE_ENTRY *old_dbe = NULL;
if (request_len < 8)
return(-0xfb);
dir_handle = (int)q[1];
sequence = GET_BE32(q + 2);
file_len = (int)q[6];
if (request_len < 8 + file_len)
return(-0xfb);
new_len = (int)q[7 + file_len];
if (request_len < 8 + file_len + new_len)
return(-0xfb);
result = nsp_salvage_dbe_from_short_handle(dir_handle, &old_dbe);
if (result < 0)
return(result);
result = nsp_salvage_recover_by_dbe(old_dbe, sequence, task, -0xfe, &scan);
if (result)
return(result);
XDPRINTF((3, 0,
"INFO SALVAGE 22/28 DONE fn=0x16 sub=0x1c dh=0x%02x seq=0x%08lx name=\"%s\"",
dir_handle, (unsigned long)sequence, scan.metadata.original_name));
return(0);
}
/*
* ncpfs ncp_ns_salvage_file() packs 87/17 as:
* byte subfunction 0x11
* byte namespace
* byte reserved
* dword scan sequence / deleted file id
* dword volume id
* dword directory/base id
* pstr new filename
* mars_nwe recovers to the original name from the trusted sidecar. The
* client supplied new filename is intentionally not used for the first pass.
*/
if (!q || request_len < 16 || q[0] != 0x11)
return(-0xfb);
namespace = (int)q[1];
scan_sequence = GET_32(q + 3);
volume = GET_32(q + 7);
directory_base = GET_32(q + 11);
if (volume >= (uint32)used_nw_volumes)
return(-0x98);
result = find_base_entry((int)volume, directory_base);
if (result < 0)
return(result);
dbe = dir_base[result];
nwp_stat(&(dbe->nwpath), "nsp_handle_salvage_recover");
if (!S_ISDIR(dbe->nwpath.statb.st_mode))
return(-0x9c);
result = nsp_salvage_recover_by_dbe(dbe, scan_sequence, task, -0x92,
&scan);
if (result)
return(result);
XDPRINTF((3, 0,
"NCP 87/17 salvage recover ns=%d seq=0x%lx vol=%lu base=0x%lx result=%d",
namespace, (unsigned long)scan_sequence, (unsigned long)volume,
(unsigned long)directory_base, result));
return(0);
}
int handle_func_salvage_purge(uint8 *q, int request_len,
uint8 *responsedata, int task)
{
int namespace;
uint32 scan_sequence;
uint32 volume;
uint32 directory_base;
DIR_BASE_ENTRY *dbe;
struct nwsalvage_scan_result scan;
int result;
(void)responsedata;
(void)task;
if (q && q[0] == 0x1d) { /* old 22/29 Purge Salvageable File */
int dir_handle;
uint32 sequence;
DIR_BASE_ENTRY *old_dbe = NULL;
if (request_len < 6)
return(-0xfb);
dir_handle = (int)q[1];
sequence = GET_BE32(q + 2);
result = nsp_salvage_dbe_from_short_handle(dir_handle, &old_dbe);
if (result < 0)
return(result);
result = nsp_salvage_purge_by_dbe(old_dbe, sequence, &scan);
if (result)
return(result);
XDPRINTF((3, 0,
"INFO SALVAGE 22/29 DONE fn=0x16 sub=0x1d dh=0x%02x seq=0x%08lx name=\"%s\"",
dir_handle, (unsigned long)sequence, scan.metadata.original_name));
return(0);
}
if (!q || request_len < 15 || q[0] != 0x12)
return(-0xfb);
namespace = (int)q[1];
scan_sequence = GET_32(q + 3);
volume = GET_32(q + 7);
directory_base = GET_32(q + 11);
if (volume >= (uint32)used_nw_volumes)
return(-0x98);
result = find_base_entry((int)volume, directory_base);
result = nsp_salvage_dbe_from_short_handle(dir_handle, &dbe);
if (result < 0)
return(result);
dbe = dir_base[result];
nwp_stat(&(dbe->nwpath), "nsp_handle_salvage_purge");
if (!S_ISDIR(dbe->nwpath.statb.st_mode))
return(-0x9c);
result = nsp_salvage_scan_by_dbe(dbe, sequence, &scan);
if (result)
return(result);
result = nsp_salvage_purge_by_dbe(dbe, scan_sequence, &scan);
result = nsp_salvage_build_old_info(&scan, responsedata);
XDPRINTF((3, 0,
"INFO SALVAGE 22/27 DONE fn=0x16 sub=0x1b dh=0x%02x seq=0x%08lx next=0x%08lx name=\"%s\"",
dir_handle, (unsigned long)sequence,
(unsigned long)scan.scan_sequence, scan.metadata.original_name));
return(result);
}
int nsp_salvage_recover_short_handle(int dir_handle, uint32 sequence, int task)
{
DIR_BASE_ENTRY *dbe;
struct nwsalvage_scan_result scan;
int result;
result = nsp_salvage_dbe_from_short_handle(dir_handle, &dbe);
if (result < 0)
return(result);
result = nsp_salvage_recover_by_dbe(dbe, sequence, task, -0xfe, &scan);
if (result)
return(result);
XDPRINTF((3, 0,
"INFO SALVAGE 87/18 DONE fn=0x57 sub=0x12 ns=0x%02x seq=0x%08lx vol=0x%08lx base=0x%08lx name=\"%s\"",
namespace, (unsigned long)scan_sequence, (unsigned long)volume,
(unsigned long)directory_base, scan.metadata.original_name));
"INFO SALVAGE 22/28 DONE fn=0x16 sub=0x1c dh=0x%02x seq=0x%08lx name=\"%s\"",
dir_handle, (unsigned long)sequence, scan.metadata.original_name));
return(0);
}
int nsp_salvage_purge_short_handle(int dir_handle, uint32 sequence)
{
DIR_BASE_ENTRY *dbe;
struct nwsalvage_scan_result scan;
int result;
result = nsp_salvage_dbe_from_short_handle(dir_handle, &dbe);
if (result < 0)
return(result);
result = nsp_salvage_purge_by_dbe(dbe, sequence, &scan);
if (result)
return(result);
XDPRINTF((3, 0,
"INFO SALVAGE 22/29 DONE fn=0x16 sub=0x1d dh=0x%02x seq=0x%08lx name=\"%s\"",
dir_handle, (unsigned long)sequence, scan.metadata.original_name));
return(0);
}
int handle_func_0x57(uint8 *p, int request_len,
uint8 *responsedata, int task)
{
@@ -3426,15 +3231,195 @@ static int code = 0;
break;
case 0x10 : /* 87/16 Scan Salvageable Files */
result = handle_func_salvage_scan(p - 1, request_len, responsedata, task);
{
uint8 *q = p - 1;
int req_namespace;
uint32 infomask;
uint32 scan_sequence;
NW_HPATH *nwpathstruct;
DIR_BASE_ENTRY *dbe;
struct nwsalvage_scan_result scan;
uint8 *rp = responsedata;
if (request_len < 18) {
result = -0xfb;
break;
}
req_namespace = (int)q[1];
infomask = GET_32(q + 3);
scan_sequence = GET_32(q + 7);
nwpathstruct = (NW_HPATH *)(q + 11);
{
uint8 *pp = nwpathstruct->pathes;
uint8 *end = q + request_len;
int k;
int bad_path = 0;
for (k = 0; k < nwpathstruct->components; k++) {
int len;
if (pp >= end) {
bad_path = 1;
break;
}
len = (int)*pp++;
if (len > (int)(end - pp)) {
bad_path = 1;
break;
}
pp += len;
}
if (bad_path) {
result = -0xfb;
break;
}
}
result = build_base(req_namespace, nwpathstruct, nwpathstruct->pathes,
0, NULL, 0);
if (result < 0)
break;
dbe = dir_base[result];
nwp_stat(&(dbe->nwpath), "nsp_handle_salvage_scan");
if (!S_ISDIR(dbe->nwpath.statb.st_mode)) {
result = -0x9c;
break;
}
result = nsp_salvage_scan_by_dbe(dbe, scan_sequence, &scan);
if (result)
break;
U32_TO_32((uint32)scan.scan_sequence, rp); rp += 4;
un_time_2_nw((time_t)scan.metadata.deleted_at, rp, 0); rp += 2;
un_date_2_nw((time_t)scan.metadata.deleted_at, rp, 0); rp += 2;
U32_TO_BE32(nsp_salvage_deletor_id(scan.metadata.deleted_by), rp); rp += 4;
U32_TO_32((uint32)scan.scan_volume, rp); rp += 4;
U32_TO_32((uint32)scan.scan_directory_base, rp); rp += 4;
result = nsp_salvage_build_info(&scan.metadata, req_namespace,
infomask, rp);
if (result < 0)
break;
result += (int)(rp - responsedata);
XDPRINTF((3, 0,
"INFO SALVAGE 87/16 DONE fn=0x57 sub=0x10 ns=0x%02x seq=0x%08lx next=0x%08lx name=\"%s\"",
req_namespace, (unsigned long)scan_sequence,
(unsigned long)scan.scan_sequence,
scan.metadata.original_name));
}
break;
case 0x11 : /* 87/17 Recover Salvageable File */
result = handle_func_salvage_recover(p - 1, request_len, responsedata, task);
{
uint8 *q = p - 1;
int req_namespace;
uint32 scan_sequence;
uint32 volume;
uint32 directory_base;
DIR_BASE_ENTRY *dbe;
struct nwsalvage_scan_result scan;
/*
* ncpfs ncp_ns_salvage_file() packs 87/17 as:
* byte subfunction 0x11
* byte namespace
* byte reserved
* dword scan sequence / deleted file id
* dword volume id
* dword directory/base id
* pstr new filename
* mars_nwe recovers to the original name from the trusted sidecar.
*/
if (request_len < 16) {
result = -0xfb;
break;
}
req_namespace = (int)q[1];
scan_sequence = GET_32(q + 3);
volume = GET_32(q + 7);
directory_base = GET_32(q + 11);
if (volume >= (uint32)used_nw_volumes) {
result = -0x98;
break;
}
result = find_base_entry((int)volume, directory_base);
if (result < 0)
break;
dbe = dir_base[result];
nwp_stat(&(dbe->nwpath), "nsp_handle_salvage_recover");
if (!S_ISDIR(dbe->nwpath.statb.st_mode)) {
result = -0x9c;
break;
}
result = nsp_salvage_recover_by_dbe(dbe, scan_sequence, task, -0x92,
&scan);
if (result)
break;
XDPRINTF((3, 0,
"INFO SALVAGE 87/17 DONE fn=0x57 sub=0x11 ns=0x%02x seq=0x%08lx vol=0x%08lx base=0x%08lx name=\"%s\"",
req_namespace, (unsigned long)scan_sequence,
(unsigned long)volume, (unsigned long)directory_base,
scan.metadata.original_name));
}
break;
case 0x12 : /* 87/18 Purge Salvageable File */
result = handle_func_salvage_purge(p - 1, request_len, responsedata, task);
{
uint8 *q = p - 1;
int req_namespace;
uint32 scan_sequence;
uint32 volume;
uint32 directory_base;
DIR_BASE_ENTRY *dbe;
struct nwsalvage_scan_result scan;
if (request_len < 15) {
result = -0xfb;
break;
}
req_namespace = (int)q[1];
scan_sequence = GET_32(q + 3);
volume = GET_32(q + 7);
directory_base = GET_32(q + 11);
if (volume >= (uint32)used_nw_volumes) {
result = -0x98;
break;
}
result = find_base_entry((int)volume, directory_base);
if (result < 0)
break;
dbe = dir_base[result];
nwp_stat(&(dbe->nwpath), "nsp_handle_salvage_purge");
if (!S_ISDIR(dbe->nwpath.statb.st_mode)) {
result = -0x9c;
break;
}
result = nsp_salvage_purge_by_dbe(dbe, scan_sequence, &scan);
if (result)
break;
XDPRINTF((3, 0,
"INFO SALVAGE 87/18 DONE fn=0x57 sub=0x12 ns=0x%02x seq=0x%08lx vol=0x%08lx base=0x%08lx name=\"%s\"",
req_namespace, (unsigned long)scan_sequence,
(unsigned long)volume, (unsigned long)directory_base,
scan.metadata.original_name));
}
break;
case 0x14 : /* Search for File or Subdir Set */

View File

@@ -3350,27 +3350,42 @@ static int handle_ncp_serv(void)
break;
case 0x1b : { /* Scan Salvageable Files, old 22/27 */
int result = handle_func_salvage_scan(p, requestlen - 2,
responsedata,
(int)(ncprequest->task));
int result;
if (requestlen < 8) result = -0xfb;
else result = nsp_salvage_scan_short_handle((int)p[1],
GET_32(p + 2),
responsedata);
if (result > -1) data_len = result;
else completition = (uint8)(-result);
}
break;
case 0x1c : { /* Recover Salvageable File, old 22/28 */
int result = handle_func_salvage_recover(p, requestlen - 2,
responsedata,
(int)(ncprequest->task));
int result;
if (requestlen < 10) result = -0xfb;
else {
int file_len = (int)p[6];
if (requestlen < 10 + file_len) result = -0xfb;
else {
int new_len = (int)p[7 + file_len];
if (requestlen < 10 + file_len + new_len)
result = -0xfb;
else
result = nsp_salvage_recover_short_handle((int)p[1],
GET_BE32(p + 2),
(int)(ncprequest->task));
}
}
if (result > -1) data_len = result;
else completition = (uint8)(-result);
}
break;
case 0x1d : { /* Purge Salvageable File, old 22/29 */
int result = handle_func_salvage_purge(p, requestlen - 2,
responsedata,
(int)(ncprequest->task));
int result;
if (requestlen < 8) result = -0xfb;
else result = nsp_salvage_purge_short_handle((int)p[1],
GET_BE32(p + 2));
if (result > -1) data_len = result;
else completition = (uint8)(-result);
}