int diff_sl(const char *lower_path, const char* upper_path, const size_t lower_root_len, const struct stat *lower_status, const struct stat *upper_status, bool verbose, FILE* script_stream, int *fts_instr,void *extra) { bool identical; if (lower_status != NULL) { switch (file_type(lower_status)) { case S_IFDIR: if (list_deleted_files(lower_path, lower_root_len, verbose) < 0) { return -1; } break; case S_IFREG: printf("Removed: %s\n", &lower_path[lower_root_len]); break; case S_IFLNK: if (symbolic_link_identical(lower_path, upper_path, &identical) < 0) { return -1; } if (!(identical && permission_identical(lower_status, upper_status))) { printf("Modified: %s\n", &lower_path[lower_root_len]); } return 0; default: fprintf(stderr, "File %s is a special file (device or pipe). We cannot handle that.\n", lower_path); return -1; } } printf("Added: %s\n", &lower_path[lower_root_len]); return 0; }
int vacuum_sl(const char *lower_path, const char* upper_path, const size_t lower_root_len, const struct stat *lower_status, const struct stat *upper_status, bool verbose, FILE* script_stream, int *fts_instr,void *extra) { if (lower_status == NULL) { return 0; } // lower does not exist if (file_type(lower_status) != S_IFLNK) { return 0; } if (!permission_identical(lower_status, upper_status)) { return 0; } bool identical; if (symbolic_link_identical(lower_path, upper_path, &identical) < 0) { return -1; } if (!identical) { return 0; } return command(script_stream, "rm %", upper_path); }
int vacuum_f(const char *lower_path, const char* upper_path, const size_t lower_root_len, const struct stat *lower_status, const struct stat *upper_status, bool verbose, FILE* script_stream, int *fts_instr) { if (lower_status == NULL) { return 0; } // lower does not exist if (file_type(lower_status) != S_IFREG) { return 0; } if (!permission_identical(lower_status, upper_status)) { return 0; } bool identical; if (regular_file_identical(lower_path, lower_status, upper_path, upper_status, &identical) < 0) { return -1; } if (!identical) { return 0; } return command(script_stream, "rm %", upper_path); }
int vacuum_dp(const char *lower_path, const char* upper_path, const size_t lower_root_len, const struct stat *lower_status, const struct stat *upper_status, bool verbose, FILE* script_stream, int *fts_instr,void *extra) { if (lower_status == NULL) { return 0; } // lower does not exist if (file_type(lower_status) != S_IFDIR) { return 0; } if (!permission_identical(lower_status, upper_status)) { return 0; } bool opaque; if (is_opaquedir(upper_path, &opaque) < 0) { return -1; } if (opaque) { return 0; } // this directory might be empty if all children are deleted in previous commands. but we simply don't test whether it's that case return command(script_stream, "rmdir --ignore-fail-on-non-empty %", upper_path); }
int merge_d(const char *lower_path, const char* upper_path, const size_t lower_root_len, const struct stat *lower_status, const struct stat *upper_status, bool verbose, FILE* script_stream, int *fts_instr,void *extra) { if (lower_status != NULL) { if (file_type(lower_status) == S_IFDIR) { bool opaque = false; if (is_opaquedir(upper_path, &opaque) < 0) { return -1; } if (opaque) { if (command(script_stream, "rm -r %", lower_path) < 0) { return -1; }; } else { if (!permission_identical(lower_status, upper_status)) { command(script_stream, "chmod --reference % %", upper_path, lower_path); } return 0; // children must be recursed, and directory itself does not need to be printed } } else { command(script_stream, "rm %", lower_path); } } *fts_instr = FTS_SKIP; return command(script_stream, "mv -T % %", upper_path, lower_path); }
int diff_d(const char *lower_path, const char* upper_path, const size_t lower_root_len, const struct stat *lower_status, const struct stat *upper_status, bool verbose, FILE* script_stream, int *fts_instr,void *extra) { if (lower_status != NULL) { if (file_type(lower_status) == S_IFDIR) { bool opaque = false; if (is_opaquedir(upper_path, &opaque) < 0) { return -1; } if (opaque) { if (list_deleted_files(lower_path, lower_root_len, verbose) < 0) { return -1; } } else { if (!permission_identical(lower_status, upper_status)) { printf("Modified: %s/\n", &lower_path[lower_root_len]); } return 0; // children must be recursed, and directory itself does not need to be printed } } else { // other types of files printf("Removed: %s\n", &lower_path[lower_root_len]); } } if (!verbose) { *fts_instr = FTS_SKIP; } printf("Added: %s/\n", &lower_path[lower_root_len]); return 0; }