/* if *file represents a directory, moves all its contents into *to, else renames * file itself to *to. */ int BLI_move(const char *file, const char *to) { int ret = recursive_operation(file, to, move_callback_pre, move_single_file, NULL); if (ret && ret != -1) { return recursive_operation(file, NULL, NULL, delete_single_file, delete_callback_post); } return ret; }
int BLI_copy(const char *file, const char *to) { char *actual_to = check_destination(file, to); int ret; ret = recursive_operation(file, actual_to, copy_callback_pre, copy_single_file, NULL); if (actual_to != to) MEM_freeN(actual_to); return ret; }
/** * Deletes the specified file or directory (depending on dir), optionally * doing recursive delete of directory contents. */ int BLI_delete(const char *file, bool dir, bool recursive) { if (recursive) { return recursive_operation(file, NULL, NULL, delete_single_file, delete_callback_post); } else if (dir) { return rmdir(file); } else { return remove(file); } }
/** * Deletes the specified file or directory (depending on dir), optionally * doing recursive delete of directory contents. */ int BLI_delete(const char *file, bool dir, bool recursive) { if (strchr(file, '"')) { printf("Error: not deleted file %s because of quote!\n", file); } else { if (recursive) { return recursive_operation(file, NULL, NULL, delete_single_file, delete_callback_post); } else if (dir) { return rmdir(file); } else { return remove(file); //BLI_snprintf(str, sizeof(str), "/bin/rm -f \"%s\"", file); } } return -1; }
/** * Scans \a startfrom, generating a corresponding destination name for each item found by * prefixing it with startto, recursively scanning subdirectories, and invoking the specified * callbacks for files and subdirectories found as appropriate. * * \param startfrom Top-level source path. * \param startto Top-level destination path. * \param callback_dir_pre Optional, to be invoked before entering a subdirectory, can return * RecursiveOp_Callback_StopRecurs to skip the subdirectory. * \param callback_file Optional, to be invoked on each file found. * \param callback_dir_post optional, to be invoked after leaving a subdirectory. * \return */ static int recursive_operation(const char *startfrom, const char *startto, RecursiveOp_Callback callback_dir_pre, RecursiveOp_Callback callback_file, RecursiveOp_Callback callback_dir_post) { struct stat st; char *from = NULL, *to = NULL; char *from_path = NULL, *to_path = NULL; struct dirent **dirlist = NULL; size_t from_alloc_len = -1, to_alloc_len = -1; int i, n, ret = 0; do { /* once */ /* ensure there's no trailing slash in file path */ from = strip_last_slash(startfrom); if (startto) to = strip_last_slash(startto); ret = lstat(from, &st); if (ret < 0) /* source wasn't found, nothing to operate with */ break; if (!S_ISDIR(st.st_mode)) { /* source isn't a directory, can't do recursive walking for it, * so just call file callback and leave */ if (callback_file != NULL) { ret = callback_file(from, to); if (ret != RecursiveOp_Callback_OK) ret = -1; } break; } n = scandir(startfrom, &dirlist, NULL, alphasort); if (n < 0) { /* error opening directory for listing */ perror("scandir"); ret = -1; break; } if (callback_dir_pre != NULL) { ret = callback_dir_pre(from, to); if (ret != RecursiveOp_Callback_OK) { if (ret == RecursiveOp_Callback_StopRecurs) /* callback requested not to perform recursive walking, not an error */ ret = 0; else ret = -1; break; } } for (i = 0; i < n; i++) { const struct dirent * const dirent = dirlist[i]; if (!strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, "..")) continue; join_dirfile_alloc(&from_path, &from_alloc_len, from, dirent->d_name); if (to) join_dirfile_alloc(&to_path, &to_alloc_len, to, dirent->d_name); if (dirent->d_type == DT_DIR) { /* recursively dig into a subfolder */ ret = recursive_operation(from_path, to_path, callback_dir_pre, callback_file, callback_dir_post); } else if (callback_file != NULL) { ret = callback_file(from_path, to_path); if (ret != RecursiveOp_Callback_OK) ret = -1; } if (ret != 0) break; } if (ret != 0) break; if (callback_dir_post != NULL) { ret = callback_dir_post(from, to); if (ret != RecursiveOp_Callback_OK) ret = -1; } } while (false); if (dirlist != NULL) { for (i = 0; i < n; i++) { free(dirlist[i]); } free(dirlist); } if (from_path != NULL) MEM_freeN(from_path); if (to_path != NULL) MEM_freeN(to_path); if (from != NULL) MEM_freeN(from); if (to != NULL) MEM_freeN(to); return ret; }