E17: symlink fixes
authorVincent Torri <vincent.torri@gmail.com>
Sat, 21 Jul 2012 13:48:35 +0000 (13:48 +0000)
committerVincent Torri <vincent.torri@gmail.com>
Sat, 21 Jul 2012 13:48:35 +0000 (13:48 +0000)
when copying symlinks, it creates a symlink to the
destination but with the name of the pointed file/folder.

It causes problems, ex: we can't copy two symlinks
pointing to the same file, because they will have the
same name.

Also when copying, if it's a link, we fill the destination
in the struct task, then, after we check overwrite with
_e_fm_op_handle_overwrite()

Here is a patch which corrects this.

Patch by Maxime Villard (rustyBSD), modified a bit by me (add 2 free() + formatting)

SVN revision: 74264

AUTHORS
src/bin/e_fm_op.c

diff --git a/AUTHORS b/AUTHORS
index be4dbca..d93288e 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -34,3 +34,4 @@ Gwanglim Lee <gl77.lee@samsung.com>
 Thomas Gstädtner <thomas@gstaedtner.net>
 q66 <quaker66@gmail.com>
 Tom Hacohen (TAsn) <tom@stosb.com>
+Maxime Villard <rustyBSD@gmx.fr>
index e593a9a..dfec0fe 100644 (file)
@@ -1163,30 +1163,30 @@ _e_fm_op_copy_dir(E_Fm_Op_Task *task)
 static int
 _e_fm_op_copy_link(E_Fm_Op_Task *task)
 {
-   int len;
-   char path[PATH_MAX];
+   char *lnk_path;
 
-   len = readlink(task->src.name, path, sizeof(path) - 1);
-   if (len < 0)
+   lnk_path = ecore_file_readlink(task->src.name);
+   if (!lnk_path)
      {
         _E_FM_OP_ERROR_SEND_WORK(task, E_FM_OP_ERROR, "Cannot read link '%s'.", task->src.name);
      }
    else
      {
-        path[len] = 0;
+        E_FM_OP_DEBUG("Creating link from '%s' to '%s'\n", lnk_path, task->dst.name);
 
-        if (symlink(path, task->dst.name) != 0)
+        if (symlink(lnk_path, task->dst.name) != 0)
           {
              if (errno == EEXIST)
                {
                   if (unlink(task->dst.name) == -1)
                     _E_FM_OP_ERROR_SEND_WORK(task, E_FM_OP_ERROR, "Cannot unlink '%s': %s.", task->dst.name);
-                  if (symlink(path, task->dst.name) == -1)
-                    _E_FM_OP_ERROR_SEND_WORK(task, E_FM_OP_ERROR, "Cannot create link from '%s' to '%s': %s.", path, task->dst.name);
+                  if (symlink(lnk_path, task->dst.name) == -1)
+                    _E_FM_OP_ERROR_SEND_WORK(task, E_FM_OP_ERROR, "Cannot create link from '%s' to '%s': %s.", lnk_path, task->dst.name);
                }
              else
-               _E_FM_OP_ERROR_SEND_WORK(task, E_FM_OP_ERROR, "Cannot create link from '%s' to '%s': %s.", path, task->dst.name);
+               _E_FM_OP_ERROR_SEND_WORK(task, E_FM_OP_ERROR, "Cannot create link from '%s' to '%s': %s.", lnk_path, task->dst.name);
           }
+        free(lnk_path);
      }
    task->dst.done += task->src.st.st_size;
    
@@ -1347,6 +1347,26 @@ _e_fm_op_copy_atom(E_Fm_Op_Task *task)
              return 1;
           }
 
+         if (S_ISLNK(task->src.st.st_mode))
+          {
+             char *dst_dir;
+
+             dst_dir = ecore_file_dir_get(task->dst.name);
+             if (dst_dir)
+               {
+                  char dst_path[PATH_MAX];
+                  const char *dst_name;
+
+                  dst_name = ecore_file_file_get(task->src.name);
+                  if ((strlen(dst_dir) + strlen(dst_name)) >= PATH_MAX)
+                    _E_FM_OP_ERROR_SEND_WORK(task, 0, "Not copying link: path too long", dst_path);
+
+                  snprintf(dst_path, sizeof(dst_path), "%s/%s", dst_dir, dst_name);
+                  task->dst.name = strdup(dst_path);
+                  free(dst_dir);
+               }
+          }
+
         if (_e_fm_op_handle_overwrite(task)) return 1;
 
         if (S_ISDIR(task->src.st.st_mode))