diff options
author | Rob Austein <sra@hactrn.net> | 2006-09-29 18:42:57 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2006-09-29 18:42:57 +0000 |
commit | 7e9cbab8aa16deee8d1f3218143f9bf99df2e3c3 (patch) | |
tree | 2339f0f7f0d52fa661046c7138da91c88e8c3a37 | |
parent | 130f40171afee88d54dde32223a07cfbfae433cd (diff) |
Clean up gratuitous use of stdarg. Clean up type qualifier mess that
that was hiding behind the stdarg mess. Add notes on what the icky
select loop will have to look like.
svn path=/rcynic/rcynic.c; revision=342
-rw-r--r-- | rcynic/rcynic.c | 95 |
1 files changed, 59 insertions, 36 deletions
diff --git a/rcynic/rcynic.c b/rcynic/rcynic.c index 09add560..1a44a184 100644 --- a/rcynic/rcynic.c +++ b/rcynic/rcynic.c @@ -66,9 +66,10 @@ typedef struct certinfo { * Program context that would otherwise be a mess of global variables. */ typedef struct rcynic_ctx { - char *jane, *rsync, *authenticated, *old_authenticated, *unauthenticated; + char *authenticated, *old_authenticated, *unauthenticated; + char *jane, *rsync_program; STACK *rsync_cache; - int indent; + int indent, rsync_timeout; int rsync_verbose, mkdir_verbose, err_verbose; } rcynic_ctx_t; @@ -390,6 +391,17 @@ static int rm_rf(const char *name) * 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 time out, we need to kill() the rsync process. + * + * Ok, this is a PITA. I don't see any portable way to use fgets() + * with non-blocking I/O, so we have to revert to raw read()/write() + * calls (after setting fcntl(fd, O_NONBLOCK)), look for the newline + * ourselves, and perhaps even copy remainig text from the buffer down + * to the bottom (or do some kind of ringbuffer thing, hmmm...no that + * doesn't work well with null terminated strings, oh well). + * + * Type signature of execvp() is weird, hence the cast. Well, ok + * ANSI/ISO const is weird to begin with, but even once one gets past + * the bizzare syntax, execvp()'s type signature is still weird. */ static int rsync_cmp(const char * const *a, const char * const *b) @@ -397,39 +409,41 @@ static int rsync_cmp(const char * const *a, const char * const *b) return strcmp(*a, *b); } -static int rsync(const rcynic_ctx_t *rc, ...) +static int rsync(const rcynic_ctx_t *rc, + const char * const *args, + const char *uri) { static char *rsync_cmd[] = { "rsync", "--update", "--times", "--copy-links", "--itemize-changes" }; - char *s, *argv[100], buffer[URI_MAX * 4], *uri = 0, path[FILENAME_MAX]; - int i, argc, pipe_fds[2], pid_status = -1; - va_list ap; + const char *argv[100]; + char *s, buffer[URI_MAX * 4], path[FILENAME_MAX]; + int i, ret, pipe_fds[2], argc = 0, pid_status = -1; +#if 0 + struct timeval tv; + fd_set rfds; + int n; +#endif pid_t pid; FILE *f; + assert(rc && uri); + memset(argv, 0, sizeof(argv)); - va_start(ap, rc); - for (argc = 0; argc < sizeof(rsync_cmd)/sizeof(*rsync_cmd); argc++) { + for (i = 0; i < sizeof(rsync_cmd)/sizeof(*rsync_cmd); i++) { assert(argc < sizeof(argv)/sizeof(*argv)); - argv[argc] = rsync_cmd[argc]; + argv[argc++] = rsync_cmd[i]; } - while ((s = va_arg(ap, char *)) != NULL) { - assert(argc < sizeof(argv)/sizeof(*argv)); - argv[argc++] = s; - if (!uri && *s != '-') - uri = s; + if (args) { + for (i = 0; args[i]; i++) { + assert(argc < sizeof(argv)/sizeof(*argv)); + argv[argc++] = args[i]; + } } - va_end(ap); - if (rc->rsync) - argv[0] = rc->rsync; - - if (!uri) { - logmsg(rc, "Couldn't extract URI from rsync command"); - return 0; - } + if (rc->rsync_program) + argv[0] = rc->rsync_program; if (!uri_to_filename(uri, path, sizeof(path), rc->unauthenticated)) { logmsg(rc, "Couldn't extract filename from URI: %s", uri); @@ -437,6 +451,9 @@ static int rsync(const rcynic_ctx_t *rc, ...) } assert(argc < sizeof(argv)/sizeof(*argv)); + argv[argc++] = uri; + + assert(argc < sizeof(argv)/sizeof(*argv)); argv[argc++] = path; assert(rc->rsync_cache != NULL); @@ -491,7 +508,7 @@ static int rsync(const rcynic_ctx_t *rc, ...) whine("dup2(1) failed\n"); else if (dup2(pipe_fds[1], 2) < 0) whine("dup2(2) failed\n"); - else if (execvp(argv[0], argv) < 0) + else if (execvp(argv[0], (char * const *) argv) < 0) whine("execvp() failed\n"); whine("last system error: "); write(2, strerror(errno), strlen(strerror(errno))); @@ -508,30 +525,33 @@ static int rsync(const rcynic_ctx_t *rc, ...) logmsg(rc, "%s", buffer); } - strcpy(buffer, uri); - if ((s = strrchr(buffer + SIZEOF_RSYNC, '/')) != NULL && s[1] == '\0') - *s = '\0'; - if ((s = strdup(buffer)) == NULL || !sk_push(rc->rsync_cache, s)) - logmsg(rc, "Couldn't cache URI %s, oh well", uri); - waitpid(pid, &pid_status, 0); if (WEXITSTATUS(pid_status)) { logmsg(rc, "rsync exited with status %d", pid_status); - return 0; + ret = 0; } else { - return 1; + ret = 1; } + + strcpy(buffer, uri); + if ((s = strrchr(buffer + SIZEOF_RSYNC, '/')) != NULL && s[1] == '\0') + *s = '\0'; + if ((s = strdup(buffer)) == NULL || !sk_push(rc->rsync_cache, s)) + logmsg(rc, "Couldn't cache URI %s, oh well", uri); + + return ret; } static int rsync_crl(const rcynic_ctx_t *rc, const char *uri) { - return rsync(rc, uri, NULL); + return rsync(rc, NULL, uri); } static int rsync_sia(const rcynic_ctx_t *rc, const char *uri) { - return rsync(rc, "--recursive", "--delete", uri, NULL); + static const char * const rsync_args[] = { "--recursive", "--delete", NULL }; + return rsync(rc, rsync_args, uri); } @@ -1092,8 +1112,11 @@ int main(int argc, char *argv[]) else if (!name_cmp(val->name, "err-verbose")) rc.err_verbose = atoi(val->value); + else if (!name_cmp(val->name, "rsync-timeout")) + rc.rsync_timeout = atoi(val->value); + else if (!name_cmp(val->name, "rsync-program")) - rc.rsync = strdup(val->value); + rc.rsync_program = strdup(val->value); } if (!rm_rf(rc.old_authenticated)) { @@ -1185,8 +1208,8 @@ int main(int argc, char *argv[]) free(rc.authenticated); free(rc.old_authenticated); free(rc.unauthenticated); - if (rc.rsync) - free(rc.rsync); + if (rc.rsync_program) + free(rc.rsync_program); finish = time(0); |