summaryrefslogtreecommitdiff
path: root/legacy/eio
diff options
context:
space:
mode:
authorCedric BAIL <cedric.bail@free.fr>2010-11-03 12:35:21 +0000
committerCedric BAIL <cedric.bail@free.fr>2010-11-03 12:35:21 +0000
commit7e9c729ce2228015208aaf84c6c7bcb2277b30c8 (patch)
tree321786d84c478df9270ee6515744c780d037925f /legacy/eio
parentc40d642b02eb5520773bd8ce64280d7eefec930e (diff)
* eio: fix recursion by detecting link and recreating them.
SVN revision: 54123
Diffstat (limited to 'legacy/eio')
-rw-r--r--legacy/eio/src/lib/eio_dir.c98
-rw-r--r--legacy/eio/src/lib/eio_private.h1
2 files changed, 86 insertions, 13 deletions
diff --git a/legacy/eio/src/lib/eio_dir.c b/legacy/eio/src/lib/eio_dir.c
index c3e2808423..288c628c5e 100644
--- a/legacy/eio/src/lib/eio_dir.c
+++ b/legacy/eio/src/lib/eio_dir.c
@@ -124,7 +124,7 @@ _eio_dir_recursiv_ls(Ecore_Thread *thread, Eio_Dir_Copy *copy, const char *targe
124 const char *dir; 124 const char *dir;
125 struct stat buffer; 125 struct stat buffer;
126 126
127 it = eina_file_direct_ls(target); 127 it = eina_file_stat_ls(target);
128 if (!it) 128 if (!it)
129 { 129 {
130 eio_file_thread_error(&copy->progress.common, thread); 130 eio_file_thread_error(&copy->progress.common, thread);
@@ -136,19 +136,16 @@ _eio_dir_recursiv_ls(Ecore_Thread *thread, Eio_Dir_Copy *copy, const char *targe
136 switch (info->type) 136 switch (info->type)
137 { 137 {
138 case EINA_FILE_UNKNOWN: 138 case EINA_FILE_UNKNOWN:
139 if (stat(info->path, &buffer) != 0) 139 eio_file_thread_error(&copy->progress.common, thread);
140 { 140 goto on_error;
141 eio_file_thread_error(&copy->progress.common, thread); 141 case EINA_FILE_DIR:
142 goto on_error; 142 if (lstat(info->path, &buffer) != 0)
143 } 143 goto on_error;
144 144
145 if (S_ISDIR(buffer.st_mode)) 145 if (S_ISDIR(buffer.st_mode))
146 dirs = eina_list_append(dirs, eina_stringshare_add(info->path)); 146 dirs = eina_list_append(dirs, eina_stringshare_add(info->path));
147 else 147 else /* It's a link we should not forget about it */
148 copy->files = eina_list_append(copy->files, eina_stringshare_add(info->path)); 148 copy->links = eina_list_append(copy->links, eina_stringshare_add(info->path));
149 break;
150 case EINA_FILE_DIR:
151 dirs = eina_list_append(dirs, eina_stringshare_add(info->path));
152 break; 149 break;
153 default: 150 default:
154 copy->files = eina_list_append(copy->files, eina_stringshare_add(info->path)); 151 copy->files = eina_list_append(copy->files, eina_stringshare_add(info->path));
@@ -192,12 +189,15 @@ _eio_dir_init(Ecore_Thread *thread,
192 189
193 /* notify main thread of the amount of work todo */ 190 /* notify main thread of the amount of work todo */
194 *step = 0; 191 *step = 0;
195 *count = eina_list_count(order->files) + eina_list_count(order->dirs) * 2; 192 *count = eina_list_count(order->files)
193 + eina_list_count(order->dirs) * 2
194 + eina_list_count(order->links);
196 eio_progress_send(thread, &order->progress, *step, *count); 195 eio_progress_send(thread, &order->progress, *step, *count);
197 196
198 /* sort the content, so we create the directory in the right order */ 197 /* sort the content, so we create the directory in the right order */
199 order->dirs = eina_list_sort(order->dirs, -1, eio_strcmp); 198 order->dirs = eina_list_sort(order->dirs, -1, eio_strcmp);
200 order->files = eina_list_sort(order->files, -1, eio_strcmp); 199 order->files = eina_list_sort(order->files, -1, eio_strcmp);
200 order->links = eina_list_sort(order->links, -1, eio_strcmp);
201 201
202 /* prepare stuff */ 202 /* prepare stuff */
203 *length_source = eina_stringshare_strlen(order->progress.source); 203 *length_source = eina_stringshare_strlen(order->progress.source);
@@ -273,6 +273,67 @@ _eio_dir_mkdir(Ecore_Thread *thread, Eio_Dir_Copy *order,
273} 273}
274 274
275static Eina_Bool 275static Eina_Bool
276_eio_dir_link(Ecore_Thread *thread, Eio_Dir_Copy *order,
277 off_t *step, off_t count,
278 int length_source, int length_dest)
279{
280 const char *link;
281 Eina_List *l;
282 char oldpath[PATH_MAX];
283 char target[PATH_MAX];
284 char buffer[PATH_MAX];
285 char *newpath;
286
287 /* Build once the base of the link target */
288 memcpy(buffer, order->progress.dest, length_dest);
289 buffer[length_dest] = '/';
290
291 /* recreate all links */
292 EINA_LIST_FOREACH(order->links, l, link)
293 {
294 ssize_t length;
295
296 /* build oldpath link */
297 _eio_dir_target(order, oldpath, link, length_source, length_dest);
298
299 /* read link target */
300 length = readlink(link, target, PATH_MAX);
301 if (length < 0)
302 goto on_error;
303
304 if (strncmp(target, order->progress.source, length_source) == 0)
305 {
306 /* The link is inside the zone to copy, so rename it */
307 memcpy(buffer + length_dest + 1, target + length_source, length - length_source + 1);
308 newpath = target;
309 }
310 else
311 {
312 /* The link is outside the zone to copy */
313 newpath = target;
314 }
315
316 /* create the link */
317 if (symlink(oldpath, newpath) != 0)
318 goto on_error;
319
320 /* inform main thread */
321 (*step)++;
322 eio_progress_send(thread, &order->progress, *step, count);
323
324 /* check for cancel request */
325 if (ecore_thread_check(thread))
326 return EINA_FALSE;
327 }
328
329 return EINA_TRUE;
330
331 on_error:
332 eio_file_thread_error(&order->progress.common, thread);
333 return EINA_FALSE;
334}
335
336static Eina_Bool
276_eio_dir_chmod(Ecore_Thread *thread, Eio_Dir_Copy *order, 337_eio_dir_chmod(Ecore_Thread *thread, Eio_Dir_Copy *order,
277 off_t *step, off_t count, 338 off_t *step, off_t count,
278 int length_source, int length_dest, 339 int length_source, int length_dest,
@@ -332,7 +393,8 @@ _eio_dir_copy_heavy(Ecore_Thread *thread, void *data)
332{ 393{
333 Eio_Dir_Copy *copy = data; 394 Eio_Dir_Copy *copy = data;
334 const char *file = NULL; 395 const char *file = NULL;
335 const char *dir = NULL; 396 const char *dir;
397 const char *link;
336 398
337 Eio_File_Progress file_copy; 399 Eio_File_Progress file_copy;
338 char target[PATH_MAX]; 400 char target[PATH_MAX];
@@ -386,6 +448,10 @@ _eio_dir_copy_heavy(Ecore_Thread *thread, void *data)
386 file_copy.dest = NULL; 448 file_copy.dest = NULL;
387 file = NULL; 449 file = NULL;
388 450
451 /* recreate link */
452 if (!_eio_dir_link(thread, copy, &step, count, length_source, length_dest))
453 goto on_error;
454
389 /* set directory right back */ 455 /* set directory right back */
390 if (!_eio_dir_chmod(thread, copy, &step, count, length_source, length_dest, EINA_FALSE)) 456 if (!_eio_dir_chmod(thread, copy, &step, count, length_source, length_dest, EINA_FALSE))
391 goto on_error; 457 goto on_error;
@@ -399,6 +465,8 @@ _eio_dir_copy_heavy(Ecore_Thread *thread, void *data)
399 eina_stringshare_del(file); 465 eina_stringshare_del(file);
400 EINA_LIST_FREE(copy->dirs, dir) 466 EINA_LIST_FREE(copy->dirs, dir)
401 eina_stringshare_del(dir); 467 eina_stringshare_del(dir);
468 EINA_LIST_FREE(copy->links, link)
469 eina_stringshare_del(link);
402 470
403 if (!ecore_thread_check(thread)) 471 if (!ecore_thread_check(thread))
404 eio_progress_send(thread, &copy->progress, count, count); 472 eio_progress_send(thread, &copy->progress, count, count);
@@ -526,6 +594,10 @@ _eio_dir_move_heavy(Ecore_Thread *thread, void *data)
526 file_move.dest = NULL; 594 file_move.dest = NULL;
527 file = NULL; 595 file = NULL;
528 596
597 /* recreate link */
598 if (!_eio_dir_link(thread, move, &step, count, length_source, length_dest))
599 goto on_error;
600
529 /* set directory right back */ 601 /* set directory right back */
530 if (!_eio_dir_chmod(thread, move, &step, count, length_source, length_dest, EINA_TRUE)) 602 if (!_eio_dir_chmod(thread, move, &step, count, length_source, length_dest, EINA_TRUE))
531 goto on_error; 603 goto on_error;
diff --git a/legacy/eio/src/lib/eio_private.h b/legacy/eio/src/lib/eio_private.h
index be9dcb890a..038a4a2f0c 100644
--- a/legacy/eio/src/lib/eio_private.h
+++ b/legacy/eio/src/lib/eio_private.h
@@ -149,6 +149,7 @@ struct _Eio_Dir_Copy
149 149
150 Eina_List *files; 150 Eina_List *files;
151 Eina_List *dirs; 151 Eina_List *dirs;
152 Eina_List *links;
152}; 153};
153 154
154struct _Eio_File_Chown 155struct _Eio_File_Chown