diff --git a/src/connect.c b/src/connect.c index 97eea83..7735332 100644 --- a/src/connect.c +++ b/src/connect.c @@ -1905,39 +1905,69 @@ int nw_mv_dir_between_handles(int sourcedirhandle, uint8 *sourcedata, int source int completition = conn_get_kpl_path(&quellpath, &qstbuff, sourcedirhandle, sourcedata, sourcedatalen, 0); + + XDPRINTF((5,0, + "nw_mv_dir_between_handles: enter src_h=%d dst_h=%d src_len=%d dst_len=%d src=`%.*s` dst=`%.*s` src_res=%d", + sourcedirhandle, zdirhandle, sourcedatalen, destdatalen, + sourcedatalen, sourcedata, destdatalen, destdata, completition)); + if (completition > -1) { char qfn[256]; char zparent[256]; char unziel[256]; - if (!S_ISDIR(qstbuff.st_mode)) + xstrcpy(qfn, build_unix_name(&quellpath, 0)); + XDPRINTF((5,0, + "nw_mv_dir_between_handles: source nwpath=`%s` unix=`%s` mode=0%o", + conn_get_nwpath_name(&quellpath), qfn, (unsigned)qstbuff.st_mode)); + + if (!S_ISDIR(qstbuff.st_mode)) { + XDPRINTF((5,0, "nw_mv_dir_between_handles: source is not directory")); return(-0x9c); + } completition = conn_get_kpl_path(&zielpath, &zstbuff, zdirhandle, destdata, destdatalen, 0); + XDPRINTF((5,0, + "nw_mv_dir_between_handles: dest resolve result=%d", + completition)); if (completition < 0) return(completition); - if (quellpath.volume != zielpath.volume) + if (quellpath.volume != zielpath.volume) { + XDPRINTF((5,0, + "nw_mv_dir_between_handles: cross-volume src_vol=%d dst_vol=%d", + quellpath.volume, zielpath.volume)); return(-0x9a); /* cross devices/volumes */ + } - xstrcpy(qfn, build_unix_name(&quellpath, 0)); xstrcpy(zparent, build_unix_name(&zielpath, 1)); if (stat(qfn, &qstbuff) || tru_eff_rights_exists(quellpath.volume, qfn, &qstbuff, - TRUSTEE_W|TRUSTEE_M|TRUSTEE_R)) + TRUSTEE_W|TRUSTEE_M|TRUSTEE_R)) { + XDPRINTF((5,0, + "nw_mv_dir_between_handles: source rights/stat failed path=`%s`", + qfn)); completition=-0x8b; - else if (stat(zparent, &zstbuff) || + } else if (stat(zparent, &zstbuff) || tru_eff_rights_exists(zielpath.volume, zparent, &zstbuff, - TRUSTEE_W)) + TRUSTEE_W)) { + XDPRINTF((5,0, + "nw_mv_dir_between_handles: dest parent rights/stat failed path=`%s`", + zparent)); completition=-0x8b; + } if (completition > -1) { int result; xstrcpy(unziel, build_unix_name(&zielpath, 0)); + XDPRINTF((5,0, + "nw_mv_dir_between_handles: moving `%s` -> `%s` parent=`%s`", + qfn, unziel, zparent)); + if (seteuid(0)) {} result = unx_mvdir((uint8 *)qfn, (uint8 *)unziel); (void)reseteuid(); @@ -1955,6 +1985,7 @@ int nw_mv_dir_between_handles(int sourcedirhandle, uint8 *sourcedata, int source } } } + XDPRINTF((5,0, "nw_mv_dir_between_handles: return %d", completition)); return(completition); } diff --git a/src/nwconn.c b/src/nwconn.c index f1af6a6..55173b2 100644 --- a/src/nwconn.c +++ b/src/nwconn.c @@ -1357,19 +1357,32 @@ static int handle_ncp_serv(void) break; } + XDPRINTF((5,0, + "NCP22/2E RenameOrMove: src_h=%d dst_h=%d attr=0x%02x src=`%s` dst=`%s`", + src_handle, (int)*q, searchattr, srcpath, dstpath)); + result = nw_mv_files(searchattr, src_handle, srcpath, srclen, (int)*q, dstpath, dstlen); + XDPRINTF((5,0, "NCP22/2E RenameOrMove: file_result=%d", result)); + /* - * nw_mv_files() is correct for file rename/move. - * Directories need the directory mover, and NCP22/2E - * can provide different source and destination handles. + * nw_mv_files() is correct for file rename/move. For a + * directory source it may return either Invalid Path (0x9c) + * or "not found" (0xff), depending on the search attribute + * shape. Directories need the directory mover, and + * NCP22/2E can provide different source/destination handles. */ - if (result == -0x9c) - result = nw_mv_dir_between_handles(src_handle, - srcpath, srclen, - (int)*q, dstpath, dstlen); + if (result == -0x9c || result == -0xff) { + int dir_result = nw_mv_dir_between_handles(src_handle, + srcpath, srclen, + (int)*q, dstpath, dstlen); + XDPRINTF((5,0, + "NCP22/2E RenameOrMove: directory fallback result=%d", + dir_result)); + result = dir_result; + } if (result < 0) completition = (uint8)(-result); }