#include #include #include #include #include #include #include #include #define PATCH_DIR ".cvn" #define BASE PATCH_DIR "/base" #define EXCLUDE_PATHS ".cvnignore" 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[]) { pid_t pid; int status; int pipefd[2]; char buf[1024]; ssize_t bytes_read; 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]); while ((bytes_read = read(pipefd[0], buf, sizeof(buf) - 1)) > 0) { buf[bytes_read] = '\0'; printf("%s", buf); } close(pipefd[0]); wait(NULL); } }