#include #include #include #include #include #include #include #include #define PATCH_DIR ".cvn" #define BASE PATCH_DIR "/base" #define EXCLUDE_PATHS PATCH_DIR "ignore" static inline void init(int argc, char *argv[]); static inline void status(int argc, char *argv[]); struct command { char *name; void (*func)(int argc, char *argv[]); }; struct command cmd[] = { {"init", init}, {"status", status}, {NULL, NULL} }; int main(int argc, char *argv[]) { int i; if (argc < 2) errx(1, "Usage: %s []", argv[0]); for (i = 0; cmd[i].name != NULL; i++) { if (strcmp(argv[1], cmd[i].name) == 0) { cmd[i].func(argc - 1, argv + 1); return 0; } } return 0; } static inline void init(int argc, char *argv[]) { int opt; char *branch; optind = 1; while ((opt = getopt(argc, argv, "b:")) != -1) { switch (opt) { case 'b': branch = optarg; break; default: break; } } if (mkdir(PATCH_DIR, 0755) == -1) { if (errno != EEXIST) err(1, "Failed to create repository"); } if (mkdir(BASE, 0755) == -1) { if (errno != EEXIST) err(1, "Failed to create base directory."); } printf("Ready\n"); } static inline void status(int argc, char *argv[]) { FILE *fp; pid_t pid; int status; int pipefd[2]; char line[1024]; if (pipe(pipefd) == -1) err(1, "pipe()"); if ((pid = fork()) == -1) err(1, "fork()"); if (pid == 0) { close(pipefd[0]); dup2(pipefd[1], STDOUT_FILENO); close(pipefd[1]); if (access(EXCLUDE_PATHS, F_OK) == 0) { char *args[] = {"diff", "-x", PATCH_DIR, "-X", EXCLUDE_PATHS, "-rq", BASE, ".", NULL}; execvp("diff", args); } else { char *args[] = {"diff", "-x", PATCH_DIR, "-rq", BASE, ".", NULL}; execvp("diff", args); } err(1, "execvp"); } else { waitpid(pid, &status, 0); close(pipefd[1]); if (!(fp = fdopen(pipefd[0], "r"))) err(1, "fdopen()"); const char *src = "Only in .: "; const char *rep = "(N) "; while (fgets(line, sizeof(line), fp) != NULL) { if (strncmp(line, src, strlen(src)) == 0) printf("%s%s", rep, line + strlen(src)); else printf("%s", line); } fclose(fp); waitpid(pid, &status, 0); } }