Skip to content

Commit

Permalink
Merge branch '4532_copy_move_attrs'
Browse files Browse the repository at this point in the history
* 4532_copy_move_attrs:
  mceditor: support ext2fs attributes.
  Ticket #4451: preserve ext2fs attributes on copy/move operations.
  • Loading branch information
aborodin committed Mar 31, 2024
2 parents 293e534 + 16fadb9 commit 25f008c
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/editor/edit.c
Original file line number Diff line number Diff line change
Expand Up @@ -2164,6 +2164,8 @@ edit_init (WEdit * edit, const WRect * r, const vfs_path_t * filename_vpath, lon
edit->stat1.st_gid = getgid ();
edit->stat1.st_mtime = 0;

edit->attrs_ok = (mc_fgetflags (filename_vpath, &edit->attrs) == 0);

edit->over_col = 0;
edit->bracket = -1;
edit->last_bracket = -1;
Expand Down
2 changes: 2 additions & 0 deletions src/editor/editcmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ edit_save_file (WEdit * edit, const vfs_path_t * filename_vpath)

(void) mc_chown (savename_vpath, edit->stat1.st_uid, edit->stat1.st_gid);
(void) mc_chmod (savename_vpath, edit->stat1.st_mode);
if (edit->attrs_ok)
(void) mc_fsetflags (savename_vpath, edit->attrs);

fd = mc_open (savename_vpath, O_CREAT | O_WRONLY | O_TRUNC | O_BINARY, edit->stat1.st_mode);
if (fd == -1)
Expand Down
3 changes: 3 additions & 0 deletions src/editor/editwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ struct WEdit
unsigned int redo_stack_reset:1; /* If 1, need clear redo stack */

struct stat stat1; /* Result of mc_fstat() on the file */
unsigned long attrs; /* Result of mc_fgetflags() on the file */
gboolean attrs_ok; /* mc_fgetflags() == 0 */

unsigned int skip_detach_prompt:1; /* Do not prompt whether to detach a file anymore */

/* syntax highlighting */
Expand Down
140 changes: 139 additions & 1 deletion src/filemanager/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -2272,6 +2272,8 @@ copy_file_file (file_op_total_context_t * tctx, file_op_context_t * ctx,
mode_t src_mode = 0; /* The mode of the source file */
struct stat src_stat, dst_stat;
mc_timesbuf_t times;
unsigned long attrs;
gboolean attrs_ok = ctx->preserve;
gboolean dst_exists = FALSE, appending = FALSE;
off_t file_size = -1;
FileProgressStatus return_status, temp_status;
Expand Down Expand Up @@ -2336,6 +2338,30 @@ copy_file_file (file_op_total_context_t * tctx, file_op_context_t * ctx,
goto ret_fast;
}

while (attrs_ok && mc_fgetflags (src_vpath, &attrs) != 0)
{
attrs_ok = FALSE;

/* don't show an error message if attributes aren't supported in this FS */
if (errno == ENOTSUP)
return_status = FILE_CONT;
else if (ctx->skip_all)
return_status = FILE_SKIPALL;
else
{
return_status =
file_error (TRUE, _("Cannot get attributes of source file \"%s\"\n%s"), src_path);
if (return_status == FILE_SKIPALL)
ctx->skip_all = TRUE;
}

if (return_status != FILE_RETRY)
break;

/* yet another attempt */
attrs_ok = TRUE;
}

if (dst_exists)
{
/* Destination already exists */
Expand Down Expand Up @@ -2379,7 +2405,30 @@ copy_file_file (file_op_total_context_t * tctx, file_op_context_t * ctx,
{
return_status = make_symlink (ctx, src_vpath, dst_vpath);
if (return_status == FILE_CONT && ctx->preserve)
{
mc_utime (dst_vpath, &times);

while (attrs_ok && mc_fsetflags (dst_vpath, attrs) != 0 && !ctx->skip_all)
{
attrs_ok = FALSE;

/* don't show an error message if attributes aren't supported in this FS */
if (errno == ENOTSUP)
return_status = FILE_CONT;
else if (return_status == FILE_SKIPALL)
ctx->skip_all = TRUE;
else
return_status =
file_error (TRUE, _("Cannot set attributes of target file \"%s\"\n%s"),
dst_path);

if (return_status != FILE_RETRY)
break;

/* yet another attempt */
attrs_ok = TRUE;
}
}
goto ret_fast;
}

Expand Down Expand Up @@ -2435,6 +2484,31 @@ copy_file_file (file_op_total_context_t * tctx, file_op_context_t * ctx,
}
}

while (attrs_ok && mc_fsetflags (dst_vpath, attrs) != 0 && !ctx->skip_all)
{
attrs_ok = FALSE;

/* don't show an error message if attributes aren't supported in this FS */
if (errno == ENOTSUP)
break;

temp_status =
file_error (TRUE, _("Cannot set attributes of target file \"%s\"\n%s"),
dst_path);
if (temp_status == FILE_SKIP)
break;
if (temp_status == FILE_SKIPALL)
ctx->skip_all = TRUE;
if (temp_status != FILE_RETRY)
{
return_status = temp_status;
goto ret_fast;
}

/* yet another attempt */
attrs_ok = TRUE;
}

return_status = FILE_CONT;
mc_utime (dst_vpath, &times);
goto ret_fast;
Expand Down Expand Up @@ -2817,10 +2891,40 @@ copy_file_file (file_op_total_context_t * tctx, file_op_context_t * ctx,
}
}

/* Always sync timestamps */
if (dst_status == DEST_FULL || dst_status == DEST_SHORT_KEEP)
{
/* Always sync timestamps */
mc_utime (dst_vpath, &times);

while (attrs_ok && mc_fsetflags (dst_vpath, attrs) != 0 && !ctx->skip_all)
{
attrs_ok = FALSE;

/* don't show an error message if attributes aren't supported in this FS */
if (errno == ENOTSUP)
{
return_status = FILE_CONT;
break;
}

temp_status = file_error (TRUE, _("Cannot set attributes for target file \"%s\"\n%s"),
dst_path);
if (temp_status == FILE_RETRY)
{
attrs_ok = TRUE;
continue;
}
if (temp_status == FILE_SKIPALL)
{
ctx->skip_all = TRUE;
return_status = FILE_CONT;
}
if (temp_status == FILE_SKIP)
return_status = FILE_CONT;
break;
}
}

if (return_status == FILE_CONT)
return_status = progress_update_one (tctx, ctx, file_size);

Expand All @@ -2844,6 +2948,8 @@ copy_dir_dir (file_op_total_context_t * tctx, file_op_context_t * ctx, const cha
{
struct vfs_dirent *next;
struct stat dst_stat, src_stat;
unsigned long attrs;
gboolean attrs_ok = ctx->preserve;
DIR *reading;
FileProgressStatus return_status = FILE_CONT;
struct link *lp;
Expand Down Expand Up @@ -2871,6 +2977,34 @@ copy_dir_dir (file_op_total_context_t * tctx, file_op_context_t * ctx, const cha
goto ret_fast;
}

while (attrs_ok && mc_fgetflags (src_vpath, &attrs) != 0)
{
attrs_ok = FALSE;

/* don't show an error message if attributes aren't supported in this FS */
if (errno == ENOTSUP)
{
return_status = FILE_CONT;
break;
}

if (ctx->skip_all)
return_status = FILE_SKIPALL;
else
{
return_status =
file_error (TRUE, _("Cannot get attributes of source directory \"%s\"\n%s"), s);
if (return_status == FILE_RETRY)
{
attrs_ok = TRUE;
continue;
}
if (return_status == FILE_SKIPALL)
ctx->skip_all = TRUE;
}
goto ret_fast;
}

if (is_in_linklist (dest_dirs, src_vpath, &src_stat) != NULL)
{
/* Don't copy a directory we created before (we don't want to copy
Expand Down Expand Up @@ -3097,6 +3231,10 @@ copy_dir_dir (file_op_total_context_t * tctx, file_op_context_t * ctx, const cha
mc_timesbuf_t times;

mc_chmod (dst_vpath, src_stat.st_mode & ctx->umask_kill);

if (attrs_ok)
mc_fsetflags (dst_vpath, attrs);

get_times (&src_stat, &times);
mc_utime (dst_vpath, &times);
}
Expand Down

0 comments on commit 25f008c

Please sign in to comment.