aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2006-09-29 18:42:57 +0000
committerRob Austein <sra@hactrn.net>2006-09-29 18:42:57 +0000
commit7e9cbab8aa16deee8d1f3218143f9bf99df2e3c3 (patch)
tree2339f0f7f0d52fa661046c7138da91c88e8c3a37
parent130f40171afee88d54dde32223a07cfbfae433cd (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.c95
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);