#include #include #include #include #include #include "lib.h" struct tmp_repo tmp_repo_init() { unsigned char rng_bytes[64]; assert(getrandom(rng_bytes, sizeof(rng_bytes), 0) == sizeof(rng_bytes)); char repo_path[70] = "/tmp/"; for (int i = 0; i < 64; i++) { repo_path[5 + i] = (char)('a' + rng_bytes[i] % 26); } repo_path[69] = '\0'; git_libgit2_init(); git_repository *repo = NULL; assert(git_repository_init(&repo, repo_path, 0) == 0); struct tmp_repo output; memcpy(output.path, repo_path, 70); output.repo = repo; return output; } void tmp_repo_deinit(struct tmp_repo repo) { pid_t pid; if ((pid = fork()) == 0) { char *argv[] = {"/usr/bin/rm", "-rf", repo.path, NULL}; execv(argv[0], argv); } assert(waitpid(pid, NULL, 0) != -1); } int check_for_backupignore() { FILE *file = fopen(".backupignore", "r"); if (file == NULL) { fprintf(stderr, "Missing .backupignore file in the current directory\n"); return 1; } else fclose(file); return 0; } void copy_over_backupignore(struct tmp_repo repo) { char cp_destination[81]; snprintf(cp_destination, 81, "%s/.gitignore", repo.path); pid_t pid; if ((pid = fork()) == 0) { char *argv[] = {"/usr/bin/cp", ".backupignore", cp_destination, NULL}; execv(argv[0], argv); } assert(waitpid(pid, NULL, 0) != -1); } int is_ignored(struct tmp_repo repo, char *path) { if (is_git_metadata_dir(path)) return 0; int ignored; assert(git_ignore_path_is_ignored(&ignored, repo.repo, path) >= 0); return ignored; } int is_git_metadata_dir(char *path) { int n = strnlen(path, PATH_MAX); for (int i = 0; i < n - 6; i++) { if (strncmp(path + i, "/.git/", 6) == 0) return 1; } return 0; }