/* Paste a directory to a new location. Designed to be called by clipboard_paste */ static bool clipboard_pastedirectory(char *src, int srclen, char *target, int targetlen, bool copy) { DIR *srcdir; int srcdirlen = strlen(src); int targetdirlen = strlen(target); bool result = true; if (!file_exists(target)) { if (!copy) { /* Just move the directory */ result = rename(src, target) == 0; #ifdef HAVE_MULTIVOLUME if (!result && errno == EXDEV) { /* Try a copy as we're going across devices */ result = clipboard_pastedirectory(src, srclen, target, targetlen, true); /* If it worked, remove the source directory */ if (result) { remove_dir(src, srclen); } } #endif return result; } else { /* Make a directory to copy things to */ result = mkdir(target) == 0; } } /* Check if something went wrong already */ if (!result) { return result; } srcdir = opendir(src); if (!srcdir) { return false; } /* This loop will exit as soon as there's a problem */ while(result) { struct dirent* entry; /* walk through the directory content */ entry = readdir(srcdir); if (!entry) break; struct dirinfo info = dir_get_info(srcdir, entry); /* append name to current directory */ snprintf(src+srcdirlen, srclen-srcdirlen, "/%s", entry->d_name); snprintf(target+targetdirlen, targetlen-targetdirlen, "/%s", entry->d_name); DEBUGF("Copy %s to %s\n", src, target); if (info.attribute & ATTR_DIRECTORY) { /* copy/move a subdirectory */ if (!strcmp((char *)entry->d_name, ".") || !strcmp((char *)entry->d_name, "..")) continue; /* skip these */ result = clipboard_pastedirectory(src, srclen, target, targetlen, copy); /* recursion */ } else { /* copy/move a file */ draw_slider(); result = clipboard_pastefile(src, target, copy); } } closedir(srcdir); if (result) { src[srcdirlen] = '\0'; /* terminate to original length */ target[targetdirlen] = '\0'; /* terminate to original length */ } return result; }
bool knob::on_motion_notify_event (GdkEventMotion *event) { if (drag==true) { draw_slider(event->x,event->y); } return TRUE; }
/* Paste a file to a new directory. Will overwrite always. */ static bool clipboard_pastefile(const char *src, const char *target, bool copy) { int src_fd, target_fd; size_t buffersize; ssize_t size, bytesread, byteswritten; char *buffer; bool result = false; if (copy) { /* See if we can get the plugin buffer for the file copy buffer */ buffer = (char *) plugin_get_buffer(&buffersize); if (buffer == NULL || buffersize < 512) { /* Not large enough, try for a disk sector worth of stack instead */ buffersize = 512; buffer = (char *) __builtin_alloca(buffersize); } if (buffer == NULL) { return false; } buffersize &= ~0x1ff; /* Round buffer size to multiple of sector size */ src_fd = open(src, O_RDONLY); if (src_fd >= 0) { target_fd = creat(target, 0666); if (target_fd >= 0) { result = true; size = filesize(src_fd); if (size == -1) { result = false; } while(size > 0) { bytesread = read(src_fd, buffer, buffersize); if (bytesread == -1) { result = false; break; } size -= bytesread; while(bytesread > 0) { byteswritten = write(target_fd, buffer, bytesread); if (byteswritten < 0) { result = false; size = 0; break; } bytesread -= byteswritten; draw_slider(); } } close(target_fd); /* Copy failed. Cleanup. */ if (!result) { remove(target); } } close(src_fd); } } else { result = rename(src, target) == 0; #ifdef HAVE_MULTIVOLUME if (!result) { if (errno == EXDEV) { /* Failed because cross volume rename doesn't work. Copy instead */ result = clipboard_pastefile(src, target, true); if (result) { result = remove(src) == 0; } } } #endif } return result; }