Changed src/filemanager/file.c to handle vfs_path_t objects.

Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
Slava Zanko 2011-11-30 00:20:26 +03:00
parent c9af137914
commit d2be823ac3
6 changed files with 187 additions and 199 deletions

View File

@ -197,19 +197,25 @@ handle_dirent (dir_list * list, const char *fltr, struct dirent *dp,
/** get info about ".." */ /** get info about ".." */
static gboolean static gboolean
get_dotdot_dir_stat (const char *path, struct stat *st) get_dotdot_dir_stat (const vfs_path_t * vpath, struct stat *st)
{ {
gboolean ret = FALSE; gboolean ret = FALSE;
if ((path != NULL) && (path[0] != '\0') && (st != NULL)) if ((vpath != NULL) && (st != NULL))
{ {
vfs_path_t *vpath; const char *path;
struct stat s;
vpath = vfs_path_build_filename (path, "..", NULL); path = vfs_path_get_by_index (vpath, 0)->path;
ret = mc_stat (vpath, &s) == 0; if (path != NULL && *path != '\0')
vfs_path_free (vpath); {
*st = s; vfs_path_t *tmp_vpath;
struct stat s;
tmp_vpath = vfs_path_append_new (vpath, "..", NULL);
ret = mc_stat (tmp_vpath, &s) == 0;
vfs_path_free (tmp_vpath);
*st = s;
}
} }
return ret; return ret;
@ -542,7 +548,7 @@ do_load_dir (const char *path, dir_list * list, sortfn * sort, gboolean lc_rever
return next_free; return next_free;
vpath = vfs_path_from_str (path); vpath = vfs_path_from_str (path);
if (get_dotdot_dir_stat (path, &st)) if (get_dotdot_dir_stat (vpath, &st))
list->list[next_free].st = st; list->list[next_free].st = st;
next_free++; next_free++;
@ -667,7 +673,7 @@ do_reload_dir (const vfs_path_t * vpath, dir_list * list, sortfn * sort, int cou
return next_free; return next_free;
} }
if (get_dotdot_dir_stat (tmp_path, &st)) if (get_dotdot_dir_stat (vpath, &st))
list->list[next_free].st = st; list->list[next_free].st = st;
next_free++; next_free++;

View File

@ -115,7 +115,8 @@ struct link
ino_t ino; ino_t ino;
short linkcount; short linkcount;
mode_t st_mode; mode_t st_mode;
char name[1]; vfs_path_t *src_vpath;
vfs_path_t *dst_vpath;
}; };
/* Status of the destination file */ /* Status of the destination file */
@ -231,6 +232,8 @@ free_linklist (struct link **lc_linklist)
for (lp = *lc_linklist; lp != NULL; lp = lp2) for (lp = *lc_linklist; lp != NULL; lp = lp2)
{ {
lp2 = lp->next; lp2 = lp->next;
vfs_path_free (lp->src_vpath);
vfs_path_free (lp->dst_vpath);
g_free (lp); g_free (lp);
} }
*lc_linklist = NULL; *lc_linklist = NULL;
@ -239,24 +242,21 @@ free_linklist (struct link **lc_linklist)
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
static int static int
is_in_linklist (struct link *lp, const char *path, struct stat *sb) is_in_linklist (struct link *lp, const vfs_path_t * vpath, struct stat *sb)
{ {
vfs_path_t *vpath; struct vfs_class *class;
vfs_path_element_t *vpath_element;
ino_t ino = sb->st_ino; ino_t ino = sb->st_ino;
dev_t dev = sb->st_dev; dev_t dev = sb->st_dev;
vpath = vfs_path_from_str (path); class = vfs_path_get_last_path_vfs (vpath);
vpath_element = vfs_path_get_by_index (vpath, -1);
while (lp != NULL) while (lp != NULL)
{ {
if (lp->vfs == vpath_element->class) if (lp->vfs == class)
if (lp->ino == ino && lp->dev == dev) if (lp->ino == ino && lp->dev == dev)
return 1; return 1;
lp = lp->next; lp = lp->next;
} }
vfs_path_free (vpath);
return 0; return 0;
} }
@ -269,89 +269,59 @@ is_in_linklist (struct link *lp, const char *path, struct stat *sb)
*/ */
static gboolean static gboolean
check_hardlinks (const char *src_name, const char *dst_name, struct stat *pstat) check_hardlinks (const vfs_path_t * src_vpath, const vfs_path_t * dst_vpath, struct stat *pstat)
{ {
struct link *lp; struct link *lp;
vfs_path_t *src_vpath, *dst_vpath;
struct vfs_class *my_vfs; struct vfs_class *my_vfs;
ino_t ino = pstat->st_ino; ino_t ino = pstat->st_ino;
dev_t dev = pstat->st_dev; dev_t dev = pstat->st_dev;
struct stat link_stat; struct stat link_stat;
const char *p;
src_vpath = vfs_path_from_str (src_name);
if ((vfs_file_class_flags (src_vpath) & VFSF_NOLINKS) != 0) if ((vfs_file_class_flags (src_vpath) & VFSF_NOLINKS) != 0)
{
vfs_path_free (src_vpath);
return FALSE; return FALSE;
}
my_vfs = vfs_path_get_by_index (src_vpath, -1)->class; my_vfs = vfs_path_get_by_index (src_vpath, -1)->class;
dst_vpath = vfs_path_from_str (dst_name);
for (lp = linklist; lp != NULL; lp = lp->next) for (lp = linklist; lp != NULL; lp = lp->next)
if (lp->vfs == my_vfs && lp->ino == ino && lp->dev == dev) if (lp->vfs == my_vfs && lp->ino == ino && lp->dev == dev)
{ {
struct vfs_class *lp_name_class; struct vfs_class *lp_name_class;
int stat_result; int stat_result;
vfs_path_t *tmp_vpath;
tmp_vpath = vfs_path_from_str (lp->name); lp_name_class = vfs_path_get_last_path_vfs (lp->src_vpath);
lp_name_class = vfs_path_get_by_index (tmp_vpath, -1)->class; stat_result = mc_stat (lp->src_vpath, &link_stat);
stat_result = mc_stat (tmp_vpath, &link_stat);
vfs_path_free (tmp_vpath);
if (!stat_result && link_stat.st_ino == ino if (stat_result == 0 && link_stat.st_ino == ino
&& link_stat.st_dev == dev && lp_name_class == my_vfs) && link_stat.st_dev == dev && lp_name_class == my_vfs)
{ {
struct vfs_class *p_class, *dst_name_class; struct vfs_class *p_class, *dst_name_class;
p = strchr (lp->name, 0) + 1; /* i.e. where the `name' file dst_name_class = vfs_path_get_last_path_vfs (dst_vpath);
was copied to */ p_class = vfs_path_get_last_path_vfs (lp->dst_vpath);
dst_name_class = vfs_path_get_by_index (dst_vpath, -1)->class;
tmp_vpath = vfs_path_from_str (p);
p_class = vfs_path_get_by_index (tmp_vpath, -1)->class;
if (dst_name_class == p_class)
{
if (!mc_stat (tmp_vpath, &link_stat))
{
if (!mc_link (tmp_vpath, dst_vpath))
{
vfs_path_free (tmp_vpath);
vfs_path_free (src_vpath);
vfs_path_free (dst_vpath);
return TRUE;
}
}
}
vfs_path_free (tmp_vpath);
if (dst_name_class == p_class &&
mc_stat (lp->dst_vpath, &link_stat) == 0 &&
mc_link (lp->dst_vpath, dst_vpath) == 0)
return TRUE;
} }
message (D_ERROR, MSG_ERROR, _("Cannot make the hardlink")); message (D_ERROR, MSG_ERROR, _("Cannot make the hardlink"));
vfs_path_free (src_vpath);
vfs_path_free (dst_vpath);
return FALSE; return FALSE;
} }
lp = (struct link *) g_try_malloc (sizeof (struct link) + strlen (src_name)
+ strlen (dst_name) + 1); lp = g_new0 (struct link, 1);
if (lp)
if (lp != NULL)
{ {
char *lpdstname;
lp->vfs = my_vfs; lp->vfs = my_vfs;
lp->ino = ino; lp->ino = ino;
lp->dev = dev; lp->dev = dev;
strcpy (lp->name, src_name); lp->src_vpath = vfs_path_clone (src_vpath);
lpdstname = lp->name + strlen (lp->name) + 1; lp->dst_vpath = vfs_path_clone (dst_vpath);
strcpy (lpdstname, dst_name);
lp->next = linklist; lp->next = linklist;
linklist = lp; linklist = lp;
} }
vfs_path_free (src_vpath);
vfs_path_free (dst_vpath);
return FALSE; return FALSE;
} }
@ -808,15 +778,20 @@ move_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, c
gboolean old_ask_overwrite; gboolean old_ask_overwrite;
vfs_path_t *src_vpath, *dst_vpath; vfs_path_t *src_vpath, *dst_vpath;
file_progress_show_source (ctx, s);
file_progress_show_target (ctx, d);
if (check_progress_buttons (ctx) == FILE_ABORT)
return FILE_ABORT;
mc_refresh ();
src_vpath = vfs_path_from_str (s); src_vpath = vfs_path_from_str (s);
dst_vpath = vfs_path_from_str (d); dst_vpath = vfs_path_from_str (d);
file_progress_show_source (ctx, src_vpath);
file_progress_show_target (ctx, dst_vpath);
if (check_progress_buttons (ctx) == FILE_ABORT)
{
return_status = FILE_ABORT;
goto ret;
}
mc_refresh ();
while (mc_lstat (src_vpath, &src_stats) != 0) while (mc_lstat (src_vpath, &src_stats) != 0)
{ {
/* Source doesn't exist */ /* Source doesn't exist */
@ -828,37 +803,32 @@ move_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, c
if (return_status == FILE_SKIPALL) if (return_status == FILE_SKIPALL)
ctx->skip_all = TRUE; ctx->skip_all = TRUE;
} }
if (return_status != FILE_RETRY) if (return_status != FILE_RETRY)
{ goto ret;
vfs_path_free (src_vpath);
vfs_path_free (dst_vpath);
return return_status;
}
} }
if (mc_lstat (dst_vpath, &dst_stats) == 0) if (mc_lstat (dst_vpath, &dst_stats) == 0)
{ {
if (src_stats.st_dev == dst_stats.st_dev && src_stats.st_ino == dst_stats.st_ino) if (src_stats.st_dev == dst_stats.st_dev && src_stats.st_ino == dst_stats.st_ino)
return warn_same_file (_("\"%s\"\nand\n\"%s\"\nare the same file"), s, d); {
return_status = warn_same_file (_("\"%s\"\nand\n\"%s\"\nare the same file"), s, d);
goto ret;
}
if (S_ISDIR (dst_stats.st_mode)) if (S_ISDIR (dst_stats.st_mode))
{ {
message (D_ERROR, MSG_ERROR, _("Cannot overwrite directory \"%s\""), d); message (D_ERROR, MSG_ERROR, _("Cannot overwrite directory \"%s\""), d);
do_refresh (); do_refresh ();
vfs_path_free (src_vpath); return_status = FILE_SKIP;
vfs_path_free (dst_vpath); goto ret;
return FILE_SKIP;
} }
if (confirm_overwrite) if (confirm_overwrite)
{ {
return_status = query_replace (ctx, d, &src_stats, &dst_stats); return_status = query_replace (ctx, d, &src_stats, &dst_stats);
if (return_status != FILE_CONT) if (return_status != FILE_CONT)
{ goto ret;
vfs_path_free (src_vpath);
vfs_path_free (dst_vpath);
return return_status;
}
} }
/* Ok to overwrite */ /* Ok to overwrite */
} }
@ -870,19 +840,13 @@ move_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, c
return_status = make_symlink (ctx, s, d); return_status = make_symlink (ctx, s, d);
if (return_status == FILE_CONT) if (return_status == FILE_CONT)
goto retry_src_remove; goto retry_src_remove;
else goto ret;
{
vfs_path_free (src_vpath);
vfs_path_free (dst_vpath);
return return_status;
}
} }
if (mc_rename (src_vpath, dst_vpath) == 0) if (mc_rename (src_vpath, dst_vpath) == 0)
{ {
vfs_path_free (src_vpath); return_status = progress_update_one (tctx, ctx, src_stats.st_size);
vfs_path_free (dst_vpath); goto ret;
return progress_update_one (tctx, ctx, src_stats.st_size);
} }
} }
#if 0 #if 0
@ -905,10 +869,8 @@ move_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, c
if (return_status == FILE_RETRY) if (return_status == FILE_RETRY)
goto retry_rename; goto retry_rename;
} }
vfs_path_free (src_vpath);
vfs_path_free (dst_vpath);
return return_status; goto ret;
} }
#endif #endif
@ -918,11 +880,7 @@ move_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, c
return_status = copy_file_file (tctx, ctx, s, d); return_status = copy_file_file (tctx, ctx, s, d);
tctx->ask_overwrite = old_ask_overwrite; tctx->ask_overwrite = old_ask_overwrite;
if (return_status != FILE_CONT) if (return_status != FILE_CONT)
{ goto ret;
vfs_path_free (src_vpath);
vfs_path_free (dst_vpath);
return return_status;
}
copy_done = TRUE; copy_done = TRUE;
@ -931,12 +889,7 @@ move_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, c
return_status = check_progress_buttons (ctx); return_status = check_progress_buttons (ctx);
if (return_status != FILE_CONT) if (return_status != FILE_CONT)
{ goto ret;
vfs_path_free (src_vpath);
vfs_path_free (dst_vpath);
return return_status;
}
mc_refresh (); mc_refresh ();
retry_src_remove: retry_src_remove:
@ -947,15 +900,13 @@ move_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, c
goto retry_src_remove; goto retry_src_remove;
if (return_status == FILE_SKIPALL) if (return_status == FILE_SKIPALL)
ctx->skip_all = TRUE; ctx->skip_all = TRUE;
goto ret;
vfs_path_free (src_vpath);
vfs_path_free (dst_vpath);
return return_status;
} }
if (!copy_done) if (!copy_done)
return_status = progress_update_one (tctx, ctx, src_stats.st_size); return_status = progress_update_one (tctx, ctx, src_stats.st_size);
ret:
vfs_path_free (src_vpath); vfs_path_free (src_vpath);
vfs_path_free (dst_vpath); vfs_path_free (dst_vpath);
@ -969,15 +920,19 @@ move_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, c
/** Don't update progress status if progress_count==NULL */ /** Don't update progress status if progress_count==NULL */
static FileProgressStatus static FileProgressStatus
erase_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s) erase_file (FileOpTotalContext * tctx, FileOpContext * ctx, const vfs_path_t * vpath)
{ {
int return_status; int return_status;
struct stat buf; struct stat buf;
vfs_path_t *vpath = vfs_path_from_str (s); char *s;
s = vfs_path_to_str (vpath);
file_progress_show_deleting (ctx, s); file_progress_show_deleting (ctx, s);
if (check_progress_buttons (ctx) == FILE_ABORT) if (check_progress_buttons (ctx) == FILE_ABORT)
{
g_free (s);
return FILE_ABORT; return FILE_ABORT;
}
mc_refresh (); mc_refresh ();
if (tctx->progress_count != 0 && mc_lstat (vpath, &buf) != 0) if (tctx->progress_count != 0 && mc_lstat (vpath, &buf) != 0)
@ -991,7 +946,7 @@ erase_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s)
return_status = file_error (_("Cannot delete file \"%s\"\n%s"), s); return_status = file_error (_("Cannot delete file \"%s\"\n%s"), s);
if (return_status == FILE_ABORT) if (return_status == FILE_ABORT)
{ {
vfs_path_free (vpath); g_free (s);
return return_status; return return_status;
} }
if (return_status == FILE_RETRY) if (return_status == FILE_RETRY)
@ -1000,8 +955,7 @@ erase_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s)
ctx->skip_all = TRUE; ctx->skip_all = TRUE;
break; break;
} }
g_free (s);
vfs_path_free (vpath);
if (tctx->progress_count == 0) if (tctx->progress_count == 0)
return FILE_CONT; return FILE_CONT;
return progress_update_one (tctx, ctx, buf.st_size); return progress_update_one (tctx, ctx, buf.st_size);
@ -1058,7 +1012,7 @@ recursive_erase (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s)
if (S_ISDIR (buf.st_mode)) if (S_ISDIR (buf.st_mode))
return_status = recursive_erase (tctx, ctx, path); return_status = recursive_erase (tctx, ctx, path);
else else
return_status = erase_file (tctx, ctx, path); return_status = erase_file (tctx, ctx, tmp_vpath);
vfs_path_free (tmp_vpath); vfs_path_free (tmp_vpath);
g_free (path); g_free (path);
} }
@ -1096,19 +1050,15 @@ recursive_erase (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s)
in the directory path points to, 0 else. */ in the directory path points to, 0 else. */
static int static int
check_dir_is_empty (const char *path) check_dir_is_empty (const vfs_path_t * vpath)
{ {
DIR *dir; DIR *dir;
struct dirent *d; struct dirent *d;
int i; int i;
vfs_path_t *vpath = vfs_path_from_str (path);
dir = mc_opendir (vpath); dir = mc_opendir (vpath);
if (!dir) if (!dir)
{
vfs_path_free (vpath);
return -1; return -1;
}
for (i = 1, d = mc_readdir (dir); d; d = mc_readdir (dir)) for (i = 1, d = mc_readdir (dir); d; d = mc_readdir (dir))
{ {
@ -1120,7 +1070,6 @@ check_dir_is_empty (const char *path)
} }
mc_closedir (dir); mc_closedir (dir);
vfs_path_free (vpath);
return i; return i;
} }
@ -1130,6 +1079,7 @@ static FileProgressStatus
erase_dir_iff_empty (FileOpContext * ctx, const char *s) erase_dir_iff_empty (FileOpContext * ctx, const char *s)
{ {
FileProgressStatus error; FileProgressStatus error;
vfs_path_t *s_vpath;
if (strcmp (s, "..") == 0) if (strcmp (s, "..") == 0)
return FILE_SKIP; return FILE_SKIP;
@ -1140,20 +1090,27 @@ erase_dir_iff_empty (FileOpContext * ctx, const char *s)
file_progress_show_deleting (ctx, s); file_progress_show_deleting (ctx, s);
if (check_progress_buttons (ctx) == FILE_ABORT) if (check_progress_buttons (ctx) == FILE_ABORT)
return FILE_ABORT; return FILE_ABORT;
mc_refresh (); mc_refresh ();
if (1 != check_dir_is_empty (s)) /* not empty or error */ s_vpath = vfs_path_from_str (s);
return FILE_CONT;
while (my_rmdir (s) != 0 && !ctx->skip_all) if (check_dir_is_empty (s_vpath) == 1) /* not empty or error */
{ {
error = file_error (_("Cannot remove directory \"%s\"\n%s"), s); while (my_rmdir (s) != 0 && !ctx->skip_all)
if (error == FILE_SKIPALL) {
ctx->skip_all = TRUE; error = file_error (_("Cannot remove directory \"%s\"\n%s"), s);
if (error != FILE_RETRY) if (error == FILE_SKIPALL)
return error; ctx->skip_all = TRUE;
if (error != FILE_RETRY)
{
vfs_path_free (s_vpath);
return error;
}
}
} }
vfs_path_free (s_vpath);
return FILE_CONT; return FILE_CONT;
} }
@ -1420,8 +1377,8 @@ FileProgressStatus
copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx, copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx,
const char *src_path, const char *dst_path) const char *src_path, const char *dst_path)
{ {
uid_t src_uid = (uid_t) - 1; uid_t src_uid = (uid_t) (-1);
gid_t src_gid = (gid_t) - 1; gid_t src_gid = (gid_t) (-1);
int src_desc, dest_desc = -1; int src_desc, dest_desc = -1;
int n_read, n_written; int n_read, n_written;
@ -1441,14 +1398,20 @@ copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx,
ctx->do_reget = 0; ctx->do_reget = 0;
return_status = FILE_RETRY; return_status = FILE_RETRY;
file_progress_show_source (ctx, src_path); dst_vpath = vfs_path_from_str (dst_path);
file_progress_show_target (ctx, dst_path); src_vpath = vfs_path_from_str (src_path);
file_progress_show_source (ctx, src_vpath);
file_progress_show_target (ctx, dst_vpath);
if (check_progress_buttons (ctx) == FILE_ABORT) if (check_progress_buttons (ctx) == FILE_ABORT)
return FILE_ABORT; {
return_status = FILE_ABORT;
goto ret_fast;
}
mc_refresh (); mc_refresh ();
dst_vpath = vfs_path_from_str (dst_path);
while (mc_stat (dst_vpath, &sb2) == 0) while (mc_stat (dst_vpath, &sb2) == 0)
{ {
if (S_ISDIR (sb2.st_mode)) if (S_ISDIR (sb2.st_mode))
@ -1465,11 +1428,11 @@ copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx,
} }
goto ret_fast; goto ret_fast;
} }
dst_exists = TRUE; dst_exists = TRUE;
break; break;
} }
src_vpath = vfs_path_from_str (src_path);
while ((*ctx->stat_func) (src_vpath, &sb) != 0) while ((*ctx->stat_func) (src_vpath, &sb) != 0)
{ {
if (ctx->skip_all) if (ctx->skip_all)
@ -1480,6 +1443,7 @@ copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx,
if (return_status == FILE_SKIPALL) if (return_status == FILE_SKIPALL)
ctx->skip_all = TRUE; ctx->skip_all = TRUE;
} }
if (return_status != FILE_RETRY) if (return_status != FILE_RETRY)
goto ret_fast; goto ret_fast;
} }
@ -1493,6 +1457,7 @@ copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx,
src_path, dst_path); src_path, dst_path);
goto ret_fast; goto ret_fast;
} }
/* Should we replace destination? */ /* Should we replace destination? */
if (tctx->ask_overwrite) if (tctx->ask_overwrite)
{ {
@ -1506,7 +1471,7 @@ copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx,
if (!ctx->do_append) if (!ctx->do_append)
{ {
/* Check the hardlinks */ /* Check the hardlinks */
if (!ctx->follow_links && sb.st_nlink > 1 && check_hardlinks (src_path, dst_path, &sb)) if (!ctx->follow_links && sb.st_nlink > 1 && check_hardlinks (src_vpath, dst_vpath, &sb))
{ {
/* We have made a hardlink - no more processing is necessary */ /* We have made a hardlink - no more processing is necessary */
return_status = FILE_CONT; return_status = FILE_CONT;
@ -1609,6 +1574,7 @@ copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx,
} }
goto ret; goto ret;
} }
src_mode = sb.st_mode; src_mode = sb.st_mode;
src_uid = sb.st_uid; src_uid = sb.st_uid;
src_gid = sb.st_gid; src_gid = sb.st_gid;
@ -1955,7 +1921,7 @@ copy_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, con
goto ret_fast; goto ret_fast;
} }
if (is_in_linklist (dest_dirs, s, &cbuf)) if (is_in_linklist (dest_dirs, src_vpath, &cbuf))
{ {
/* Don't copy a directory we created before (we don't want to copy /* Don't copy a directory we created before (we don't want to copy
infinitely if a directory is copied into itself) */ infinitely if a directory is copied into itself) */
@ -1968,7 +1934,7 @@ copy_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, con
/* FIXME: In this step we should do something /* FIXME: In this step we should do something
in case the destination already exist */ in case the destination already exist */
/* Check the hardlinks */ /* Check the hardlinks */
if (ctx->preserve && cbuf.st_nlink > 1 && check_hardlinks (s, d, &cbuf)) if (ctx->preserve && cbuf.st_nlink > 1 && check_hardlinks (src_vpath, dst_vpath, &cbuf))
{ {
/* We have made a hardlink - no more processing is necessary */ /* We have made a hardlink - no more processing is necessary */
goto ret_fast; goto ret_fast;
@ -1989,7 +1955,7 @@ copy_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, con
goto ret_fast; goto ret_fast;
} }
if (is_in_linklist (parent_dirs, s, &cbuf)) if (is_in_linklist (parent_dirs, src_vpath, &cbuf))
{ {
/* we found a cyclic symbolic link */ /* we found a cyclic symbolic link */
message (D_ERROR, MSG_ERROR, _("Cannot copy cyclic symbolic link\n\"%s\""), s); message (D_ERROR, MSG_ERROR, _("Cannot copy cyclic symbolic link\n\"%s\""), s);
@ -1997,7 +1963,7 @@ copy_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, con
goto ret_fast; goto ret_fast;
} }
lp = g_new (struct link, 1); lp = g_new0 (struct link, 1);
lp->vfs = vfs_path_get_by_index (src_vpath, -1)->class; lp->vfs = vfs_path_get_by_index (src_vpath, -1)->class;
lp->ino = cbuf.st_ino; lp->ino = cbuf.st_ino;
lp->dev = cbuf.st_dev; lp->dev = cbuf.st_dev;
@ -2148,11 +2114,12 @@ copy_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, con
if (ctx->erase_at_end) if (ctx->erase_at_end)
{ {
static struct link *tail; static struct link *tail;
size_t len = strlen (path);
lp = g_malloc (sizeof (struct link) + len); lp = g_new0 (struct link, 1);
strncpy (lp->name, path, len + 1); lp->src_vpath = vfs_path_clone (tmp_vpath);
lp->st_mode = buf.st_mode; lp->st_mode = buf.st_mode;
lp->next = NULL; lp->next = NULL;
if (erase_list != NULL) if (erase_list != NULL)
{ {
tail->next = lp; tail->next = lp;
@ -2168,7 +2135,7 @@ copy_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, con
return_status = erase_dir_iff_empty (ctx, path); return_status = erase_dir_iff_empty (ctx, path);
} }
else else
return_status = erase_file (tctx, ctx, path); return_status = erase_file (tctx, ctx, tmp_vpath);
} }
} }
g_free (path); g_free (path);
@ -2221,19 +2188,25 @@ move_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, con
src_vpath = vfs_path_from_str (s); src_vpath = vfs_path_from_str (s);
dst_vpath = vfs_path_from_str (d); dst_vpath = vfs_path_from_str (d);
file_progress_show_source (ctx, s); file_progress_show_source (ctx, src_vpath);
file_progress_show_target (ctx, d); file_progress_show_target (ctx, dst_vpath);
if (check_progress_buttons (ctx) == FILE_ABORT) if (check_progress_buttons (ctx) == FILE_ABORT)
return FILE_ABORT; {
return_status = FILE_ABORT;
goto ret_fast;
}
mc_refresh (); mc_refresh ();
mc_stat (src_vpath, &sbuf); mc_stat (src_vpath, &sbuf);
dstat_ok = (mc_stat (dst_vpath, &dbuf) == 0); dstat_ok = (mc_stat (dst_vpath, &dbuf) == 0);
if (dstat_ok && sbuf.st_dev == dbuf.st_dev && sbuf.st_ino == dbuf.st_ino) if (dstat_ok && sbuf.st_dev == dbuf.st_dev && sbuf.st_ino == dbuf.st_ino)
return warn_same_file (_("\"%s\"\nand\n\"%s\"\nare the same directory"), s, d); {
return_status = warn_same_file (_("\"%s\"\nand\n\"%s\"\nare the same directory"), s, d);
goto ret_fast;
}
if (!dstat_ok) if (!dstat_ok)
destdir = g_strdup (d); /* destination doesn't exist */ destdir = g_strdup (d); /* destination doesn't exist */
@ -2272,11 +2245,10 @@ move_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, con
if (return_status == FILE_RETRY) if (return_status == FILE_RETRY)
goto retry_dst_stat; goto retry_dst_stat;
} }
g_free (destdir); g_free (destdir);
vfs_path_free (destdir_vpath); vfs_path_free (destdir_vpath);
vfs_path_free (src_vpath); goto ret_fast;
vfs_path_free (dst_vpath);
return return_status;
} }
retry_rename: retry_rename:
@ -2318,10 +2290,14 @@ move_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, con
{ {
if (S_ISDIR (erase_list->st_mode)) if (S_ISDIR (erase_list->st_mode))
{ {
return_status = erase_dir_iff_empty (ctx, erase_list->name); char *src_path;
src_path = vfs_path_to_str (erase_list->src_vpath);
return_status = erase_dir_iff_empty (ctx, src_path);
g_free (src_path);
} }
else else
return_status = erase_file (tctx, ctx, erase_list->name); return_status = erase_file (tctx, ctx, erase_list->src_vpath);
lp = erase_list; lp = erase_list;
erase_list = erase_list->next; erase_list = erase_list->next;
g_free (lp); g_free (lp);
@ -2338,6 +2314,7 @@ move_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, con
erase_list = erase_list->next; erase_list = erase_list->next;
g_free (lp); g_free (lp);
} }
ret_fast:
vfs_path_free (src_vpath); vfs_path_free (src_vpath);
vfs_path_free (dst_vpath); vfs_path_free (dst_vpath);
return return_status; return return_status;
@ -2349,19 +2326,27 @@ move_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s, con
/* {{{ Erase routines */ /* {{{ Erase routines */
FileProgressStatus FileProgressStatus
erase_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s) erase_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const vfs_path_t * s_vpath)
{ {
FileProgressStatus error; FileProgressStatus error;
char *s;
if (strcmp (s, "..") == 0) s = vfs_path_to_str (s_vpath);
return FILE_SKIP;
if (strcmp (s, ".") == 0) /*
return FILE_SKIP; if (strcmp (s, "..") == 0)
return FILE_SKIP;
if (strcmp (s, ".") == 0)
return FILE_SKIP;
*/
file_progress_show_deleting (ctx, s); file_progress_show_deleting (ctx, s);
if (check_progress_buttons (ctx) == FILE_ABORT) if (check_progress_buttons (ctx) == FILE_ABORT)
{
g_free (s);
return FILE_ABORT; return FILE_ABORT;
}
mc_refresh (); mc_refresh ();
/* The old way to detect a non empty directory was: /* The old way to detect a non empty directory was:
@ -2371,23 +2356,27 @@ erase_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s)
we would have to check also for EIO. I hope the new way is we would have to check also for EIO. I hope the new way is
fool proof. (Norbert) fool proof. (Norbert)
*/ */
error = check_dir_is_empty (s); error = check_dir_is_empty (s_vpath);
if (error == 0) if (error == 0)
{ /* not empty */ { /* not empty */
error = query_recursive (ctx, s); error = query_recursive (ctx, s);
if (error == FILE_CONT) if (error == FILE_CONT)
return recursive_erase (tctx, ctx, s); error = recursive_erase (tctx, ctx, s);
else g_free (s);
return error; return error;
} }
while (my_rmdir (s) == -1 && !ctx->skip_all) while (my_rmdir (s) == -1 && !ctx->skip_all)
{ {
error = file_error (_("Cannot remove directory \"%s\"\n%s"), s); error = file_error (_("Cannot remove directory \"%s\"\n%s"), s);
if (error != FILE_RETRY) if (error != FILE_RETRY)
{
g_free (s);
return error; return error;
}
} }
g_free (s);
return FILE_CONT; return FILE_CONT;
} }
@ -2845,9 +2834,9 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl
if (operation == OP_DELETE) if (operation == OP_DELETE)
{ {
if (S_ISDIR (src_stat.st_mode)) if (S_ISDIR (src_stat.st_mode))
value = erase_dir (tctx, ctx, source_with_path_str); value = erase_dir (tctx, ctx, source_with_vpath);
else else
value = erase_file (tctx, ctx, source_with_path_str); value = erase_file (tctx, ctx, source_with_vpath);
} }
else else
{ {
@ -2945,9 +2934,9 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl
if (operation == OP_DELETE) if (operation == OP_DELETE)
{ {
if (S_ISDIR (src_stat.st_mode)) if (S_ISDIR (src_stat.st_mode))
value = erase_dir (tctx, ctx, source_with_path_str); value = erase_dir (tctx, ctx, source_with_vpath);
else else
value = erase_file (tctx, ctx, source_with_path_str); value = erase_file (tctx, ctx, source_with_vpath);
} }
else else
{ {

View File

@ -44,7 +44,8 @@ FileProgressStatus copy_dir_dir (FileOpTotalContext * tctx, FileOpContext * ctx,
const char *s, const char *d, const char *s, const char *d,
gboolean toplevel, gboolean move_over, gboolean do_delete, gboolean toplevel, gboolean move_over, gboolean do_delete,
struct link *parent_dirs); struct link *parent_dirs);
FileProgressStatus erase_dir (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s); FileProgressStatus erase_dir (FileOpTotalContext * tctx, FileOpContext * ctx,
const vfs_path_t * vpath);
gboolean panel_operate (void *source_panel, FileOperation op, gboolean force_single); gboolean panel_operate (void *source_panel, FileOperation op, gboolean force_single);

View File

@ -803,7 +803,7 @@ file_progress_show_total (FileOpTotalContext * tctx, FileOpContext * ctx, uintma
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
void void
file_progress_show_source (FileOpContext * ctx, const char *s) file_progress_show_source (FileOpContext * ctx, const vfs_path_t * s_vpath)
{ {
FileOpContextUI *ui; FileOpContextUI *ui;
@ -812,23 +812,14 @@ file_progress_show_source (FileOpContext * ctx, const char *s)
ui = ctx->ui; ui = ctx->ui;
if (s != NULL) if (s_vpath != NULL)
{ {
#ifdef WITH_FULL_PATHS char *s;
size_t i;
char *cwd_str;
cwd_str = vfs_path_to_str (current_panel->cwd_vpath); s = vfs_path_tokens_get (s_vpath, -1, 1);
i = strlen (cwd_str);
/* We remove the full path we have added before */
if (strncmp (s, cwd_str, i) == 0)
if (s[i] == PATH_SEP)
s += i + 1;
g_free (cwd_str);
#endif /* WITH_FULL_PATHS */
label_set_text (ui->file_label[0], _("Source")); label_set_text (ui->file_label[0], _("Source"));
label_set_text (ui->file_string[0], truncFileString (ui, s)); label_set_text (ui->file_string[0], truncFileString (ui, s));
g_free (s);
} }
else else
{ {
@ -840,7 +831,7 @@ file_progress_show_source (FileOpContext * ctx, const char *s)
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
void void
file_progress_show_target (FileOpContext * ctx, const char *s) file_progress_show_target (FileOpContext * ctx, const vfs_path_t * s_vpath)
{ {
FileOpContextUI *ui; FileOpContextUI *ui;
@ -849,10 +840,14 @@ file_progress_show_target (FileOpContext * ctx, const char *s)
ui = ctx->ui; ui = ctx->ui;
if (s != NULL) if (s_vpath != NULL)
{ {
char *s;
s = vfs_path_to_str (s_vpath);
label_set_text (ui->file_label[1], _("Target")); label_set_text (ui->file_label[1], _("Target"));
label_set_text (ui->file_string[1], truncFileStringSecure (ui, s)); label_set_text (ui->file_string[1], truncFileStringSecure (ui, s));
g_free (s);
} }
else else
{ {

View File

@ -36,8 +36,8 @@ void file_progress_show (FileOpContext * ctx, off_t done, off_t total,
void file_progress_show_count (FileOpContext * ctx, size_t done, size_t total); void file_progress_show_count (FileOpContext * ctx, size_t done, size_t total);
void file_progress_show_total (FileOpTotalContext * tctx, FileOpContext * ctx, void file_progress_show_total (FileOpTotalContext * tctx, FileOpContext * ctx,
uintmax_t copied_bytes, gboolean show_summary); uintmax_t copied_bytes, gboolean show_summary);
void file_progress_show_source (FileOpContext * ctx, const char *path); void file_progress_show_source (FileOpContext * ctx, const vfs_path_t * s_vpath);
void file_progress_show_target (FileOpContext * ctx, const char *path); void file_progress_show_target (FileOpContext * ctx, const vfs_path_t * path);
void file_progress_show_deleting (FileOpContext * ctx, const char *path); void file_progress_show_deleting (FileOpContext * ctx, const char *path);
/*** inline functions ****************************************************************************/ /*** inline functions ****************************************************************************/

View File

@ -874,37 +874,34 @@ tree_rmdir (void *data)
WTree *tree = data; WTree *tree = data;
FileOpContext *ctx; FileOpContext *ctx;
FileOpTotalContext *tctx; FileOpTotalContext *tctx;
char *selected_ptr_name;
if (!tree->selected_ptr) if (!tree->selected_ptr)
return; return;
selected_ptr_name = vfs_path_to_str (tree->selected_ptr->name);
if (confirm_delete) if (confirm_delete)
{ {
char *buf; char *buf;
int result; int result;
char *selected_ptr_name;
selected_ptr_name = vfs_path_to_str (tree->selected_ptr->name);
buf = g_strdup_printf (_("Delete %s?"), selected_ptr_name); buf = g_strdup_printf (_("Delete %s?"), selected_ptr_name);
g_free (selected_ptr_name);
result = query_dialog (Q_ ("DialogTitle|Delete"), buf, D_ERROR, 2, _("&Yes"), _("&No")); result = query_dialog (Q_ ("DialogTitle|Delete"), buf, D_ERROR, 2, _("&Yes"), _("&No"));
g_free (buf); g_free (buf);
if (result != 0) if (result != 0)
{
g_free (selected_ptr_name);
return; return;
}
} }
ctx = file_op_context_new (OP_DELETE); ctx = file_op_context_new (OP_DELETE);
tctx = file_op_total_context_new (); tctx = file_op_total_context_new ();
file_op_context_create_ui (ctx, FALSE, FILEGUI_DIALOG_ONE_ITEM); file_op_context_create_ui (ctx, FALSE, FILEGUI_DIALOG_ONE_ITEM);
if (erase_dir (tctx, ctx, selected_ptr_name) == FILE_CONT) if (erase_dir (tctx, ctx, tree->selected_ptr->name) == FILE_CONT)
tree_forget (tree); tree_forget (tree);
file_op_total_context_destroy (tctx); file_op_total_context_destroy (tctx);
file_op_context_destroy (ctx); file_op_context_destroy (ctx);
g_free (selected_ptr_name);
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */