diff options
-rw-r--r-- | rcynic/rcynic.c | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/rcynic/rcynic.c b/rcynic/rcynic.c index e99b351d..33d6b252 100644 --- a/rcynic/rcynic.c +++ b/rcynic/rcynic.c @@ -56,7 +56,6 @@ static void vlogmsg(char *fmt, va_list ap) putchar('\n'); } - static void logmsg(char *fmt, ...) { va_list ap; @@ -89,20 +88,43 @@ static void fatal(int retval, char *fmt, ...) } /* - * Subprocess manipulation. + * Run rsync. + * + * This probably isn't paranoid enough. Should use select() to do + * some kind of timeout when rsync is taking too long. Breaking the + * log stream into lines without fgets() is a pain, maybe setting + * nonblocking I/O before calling fdopen() would suffice to let us + * use select()? If we can time out, we need to be able to kill() + * the rsync process. Might need to use waitpid() instead of wait() + * so we can specify the pid we want and WNOHANG. */ -static int vrun(char *prog, va_list ap) +static char *rsync_cmd[] = { + "rsync", "--update", "--times", "--copy-links", "--itemize-changes" +}; + +static int rsync(char *args, ...) { - char *argv[100], buffer[2000]; + char *uri = 0, *argv[100], buffer[2000]; int argc, pipe_fds[2], n, pid_status = -1; + va_list ap; FILE *f; - argv[argc = 0] = prog; + for (argc = 0; argc < sizeof(rsync_cmd)/sizeof(*rsync_cmd); argc++) + argv[argc] = rsync_cmd[argc]; + argv[argc] = args; + va_start(ap, args); while (argv[argc++]) { assert(argc < sizeof(argv)/sizeof(*argv)); argv[argc] = va_arg(ap, char *); + if (!uri && argv[argc] && *argv[argc] != '-') + uri = argv[argc]; } + va_end(ap); + + /* + * This is where we'd check to see if we've already pulled this URI. + */ if (pipe(pipe_fds) < 0) fatal(1, "pipe() failed"); @@ -116,13 +138,14 @@ static int vrun(char *prog, va_list ap) fatal(-2, "dup2(1) failed"); if (dup2(pipe_fds[1], 2) < 0) fatal(-3, "dup2(2) failed"); - execvp(prog, argv); + execvp(argv[0], argv); fatal(-4, "execvp() failed"); } close(pipe_fds[1]); + if ((f = fdopen(pipe_fds[0], "r")) == NULL) - fatal(1, "Couldn't open output of forked process"); + fatal(1, "Couldn't open rsync's output stream"); while (fgets(buffer, sizeof(buffer), f)) { char *s = strchr(buffer, '\n'); @@ -134,23 +157,13 @@ static int vrun(char *prog, va_list ap) wait(&pid_status); if (WEXITSTATUS(pid_status)) { - logmsg("Forked process exited with status %d", pid_status); + logmsg("rsync exited with status %d", pid_status); return 0; } else { return 1; } } -static int run(char *prog, ...) -{ - int ret; - va_list ap; - va_start(ap, prog); - ret = vrun(prog, ap); - va_end(ap); - return ret; -} - /* * Make a directory if it doesn't already exist. */ |