diff --git a/include/namspace.h b/include/namspace.h index bf45682..c2a4746 100644 --- a/include/namspace.h +++ b/include/namspace.h @@ -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); diff --git a/src/namspace.c b/src/namspace.c index ad680f0..a6eed09 100644 --- a/src/namspace.c +++ b/src/namspace.c @@ -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 */ diff --git a/src/nwconn.c b/src/nwconn.c index 78643a2..07f7024 100644 --- a/src/nwconn.c +++ b/src/nwconn.c @@ -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); }