Directory Rename/Move über NCP22/2E
All checks were successful
Source release / source-package (push) Successful in 37s

This commit is contained in:
Mario Fetka
2026-05-25 18:13:31 +02:00
parent de5dfbd4a8
commit cb63088676
3 changed files with 83 additions and 0 deletions

View File

@@ -120,6 +120,8 @@ extern int nw_mv_files(int searchattrib,
extern int mv_dir(int dir_handle, uint8 *sourcedata, int qlen,
uint8 *destdata, int destdatalen);
extern int nw_mv_dir_between_handles(int sourcedirhandle, uint8 *sourcedata, int qlen,
int zdirhandle, uint8 *destdata, int destdatalen);
extern int nw_unlink_node(int volume, uint8 *unname, struct stat *stb);
extern int nw_creat_node(int volume, uint8 *unname, int mode);

View File

@@ -1889,6 +1889,76 @@ int mv_dir(int dir_handle, uint8 *sourcedata, int sourcedatalen,
return(completition);
}
int nw_mv_dir_between_handles(int sourcedirhandle, uint8 *sourcedata, int sourcedatalen,
int zdirhandle, uint8 *destdata, int destdatalen)
/*
* Rename/move a directory where source and destination are expressed using
* separate directory handles. This is needed by NCP 22/46 Rename Or Move
* (old). The older mv_dir() helper only supports the classic NCP 22/15
* style where the destination is just a new name below the source parent.
*/
{
NW_PATH quellpath;
NW_PATH zielpath;
struct stat qstbuff;
struct stat zstbuff;
int completition = conn_get_kpl_path(&quellpath, &qstbuff,
sourcedirhandle,
sourcedata, sourcedatalen, 0);
if (completition > -1) {
char qfn[256];
char zparent[256];
char unziel[256];
if (!S_ISDIR(qstbuff.st_mode))
return(-0x9c);
completition = conn_get_kpl_path(&zielpath, &zstbuff,
zdirhandle,
destdata, destdatalen, 0);
if (completition < 0)
return(completition);
if (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))
completition=-0x8b;
else if (stat(zparent, &zstbuff) ||
tru_eff_rights_exists(zielpath.volume, zparent, &zstbuff,
TRUSTEE_W))
completition=-0x8b;
if (completition > -1) {
int result;
xstrcpy(unziel, build_unix_name(&zielpath, 0));
if (seteuid(0)) {}
result = unx_mvdir((uint8 *)qfn, (uint8 *)unziel);
(void)reseteuid();
XDPRINTF((4,0, "rendir/movedir result=%d, '%s'->'%s'",
result, qfn, unziel));
if (!result)
completition = 0;
else {
if (result == EEXIST)
completition=-0x92; /* already exists */
else if (result == EXDEV)
completition=-0x9a; /* cross devices */
else completition=-0x9c; /* wrong path */
}
}
}
return(completition);
}
static int change_dir_entry( NW_DIR *dir, int volume,
uint8 *path,
int dev, ino_t inode,

View File

@@ -1360,6 +1360,17 @@ static int handle_ncp_serv(void)
result = nw_mv_files(searchattr,
src_handle, srcpath, srclen,
(int)*q, dstpath, dstlen);
/*
* nw_mv_files() is correct for file rename/move.
* Directories need the directory mover, and NCP22/2E
* can provide different source and destination handles.
*/
if (result == -0x9c)
result = nw_mv_dir_between_handles(src_handle,
srcpath, srclen,
(int)*q, dstpath, dstlen);
if (result < 0) completition = (uint8)(-result);
}
break;