static int _move_single(Move * move, char const * src, char const * dst) { int ret; struct stat st; if(lstat(src, &st) != 0 && errno == ENOENT) /* XXX TOCTOU */ return _move_filename_error(move, src, 1); if(*(move->prefs) & PREFS_i && (lstat(dst, &st) == 0 || errno != ENOENT) && _move_filename_confirm(move, dst) != 1) return 0; if(rename(src, dst) == 0) return 0; if(errno != EXDEV) return _move_filename_error(move, src, 1); if(unlink(dst) != 0 && errno != ENOENT) return _move_filename_error(move, dst, 1); if(lstat(src, &st) != 0) return _move_filename_error(move, dst, 1); if(S_ISDIR(st.st_mode)) ret = _single_dir(move, src, dst); else if(S_ISFIFO(st.st_mode)) ret = _single_fifo(move, src, dst); else if(S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) ret = _single_nod(move, src, dst, st.st_mode, st.st_rdev); else if(S_ISLNK(st.st_mode)) ret = _single_symlink(move, src, dst); else if(!S_ISREG(st.st_mode)) /* FIXME not implemented */ { errno = ENOSYS; return _move_filename_error(move, src, 1); } else ret = _single_regular(move, src, dst); if(ret != 0) return ret; _single_p(move, dst, &st); return 0; }
static int _copy_single(Copy * copy, char const * src, char const * dst) { int ret; char * p; struct stat st; struct stat st2; guint timeout; if((p = g_filename_to_utf8(src, -1, NULL, NULL, NULL)) != NULL) gtk_label_set_text(GTK_LABEL(copy->flabel), p); else gtk_label_set_text(GTK_LABEL(copy->flabel), src); free(p); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(copy->fprogress), 0.0); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(copy->fprogress), ""); if(*(copy->prefs) & PREFS_P) { /* do not follow symlinks */ if(browser_vfs_lstat(src, &st) != 0 && errno == ENOENT) return _copy_filename_error(copy, src, 1); } else if(browser_vfs_stat(src, &st) != 0 && errno == ENOENT) /* follow symlinks */ return _copy_filename_error(copy, src, 1); if(browser_vfs_lstat(dst, &st2) == 0) { if(st.st_dev == st2.st_dev && st.st_ino == st2.st_ino) { fprintf(stderr, "%s: %s: \"%s\"%s\n", PROGNAME_COPY, dst, src, _(" is identical (not copied)")); return 0; } if(*(copy->prefs) & PREFS_i && _copy_filename_confirm(copy, dst) != 1) return 0; if(unlink(dst) != 0) return _copy_filename_error(copy, dst, 1); } if(S_ISDIR(st.st_mode)) ret = _single_dir(copy, src, dst, st.st_mode & 0777); else if(S_ISFIFO(st.st_mode)) ret = _single_fifo(copy, dst, st.st_mode & 0666); else if(S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) ret = _single_nod(copy, src, dst, st.st_mode, st.st_rdev); else if(S_ISLNK(st.st_mode)) ret = _single_symlink(copy, src, dst); else if(S_ISREG(st.st_mode)) { ret = _single_regular(copy, src, dst, st.st_mode & 0777); timeout = g_timeout_add(250, _single_timeout, copy); gtk_main(); /* XXX ugly */ g_source_remove(timeout); } else { errno = ENOSYS; return _copy_error(copy, src, 1); } if(ret != 0) return ret; if(*(copy->prefs) & PREFS_p) /* XXX TOCTOU */ _single_p(copy, dst, &st); return 0; }