--- main.c.orig Sun Jun 19 22:38:49 2005 +++ main.c Sun Jun 19 22:40:06 2005 @@ -50,6 +50,8 @@ { lprintf(-1, "Usage: %s [options] supfile [destDir]\n", basename(argv0)); lprintf(-1, " Options:\n"); + lprintf(-1, USAGE_OPTFMT, "-1", + "Don't retry automatically on failure (same as \"-r 0\")"); lprintf(-1, USAGE_OPTFMT, "-a", "Require server to authenticate itself to us"); lprintf(-1, USAGE_OPTFMT, "-b base", @@ -64,6 +66,8 @@ "Verbosity level (0..2, default 1)"); lprintf(-1, USAGE_OPTFMT, "-p port", "Alternate server port (default 5999)"); + lprintf(-1, USAGE_OPTFMT, "-r n", + "Maximum retries on transient errors (default unlimited)"); lprintf(-1, USAGE_OPTFMT, "-v", "Print version and exit"); lprintf(-1, USAGE_OPTFMT, "-z", "Enable compression for all " "collections"); @@ -77,16 +81,21 @@ struct config *config; char *argv0, *base, *colldir, *host, *file, *lockfile; in_port_t port; - int c, compress, error, lockfd, lflag = 0; + int c, compress, error, lockfd, retries, i, lflag = 0; + retries = -1; auth_required = 0; port = 0; + i = 0; compress = 0; lockfd = 0; argv0 = argv[0]; base = colldir = host = lockfile = NULL; - while ((c = getopt(argc, argv, "ab:c:gh:l:L:p:P:vzZ")) != -1) { + while ((c = getopt(argc, argv, "1ab:c:gh:l:L:p:P:r:vzZ")) != -1) { switch (c) { + case '1': + retries = 0; + break; case 'a': auth_required = 1; break; @@ -143,6 +152,9 @@ return (1); } break; + case 'r': + retries = strtol(optarg, NULL, 0); + break; case 'v': lprintf(-1, "Csup version 0.1\n"); return (0); @@ -175,11 +187,27 @@ config = config_init(file, host, base, colldir, port, compress); lprintf(2, "Connecting to %s\n", config->host); auth_read_records(); - error = cvsup_connect(config); - if (error) - return (1); - lprintf(1, "Connected to %s\n", config->host); - cvsup_init(config); + while (1) { + error = cvsup_connect(config); + if (i == retries && error) + break; + if (!error) + lprintf(1, "Connected to %s\n", config->host); + if (error && (retries > 0 || retries == -1)) { + cvsup_timeout(300); + i++; + continue; + } + error = cvsup_init(config); + if (i == retries && error) + break; + if (error == -2) { + cvsup_timeout(300); + i++; + continue; + } else + break; + } if (lflag) close(lockfd); auth_free_records(); --- proto.c.orig Sun Jun 19 22:38:44 2005 +++ proto.c Sun Jun 19 22:38:53 2005 @@ -150,7 +150,7 @@ tok = strsep(&line, " "); } else if (strcmp(tok, "!") == 0) { lprintf(-1, "Rejected by server: %s\n", line); - return (-1); + return (-2); } else goto bad; lprintf(2, "Server software version: %s\n", tok != NULL ? tok : "."); @@ -507,4 +507,17 @@ mux_fini(); lprintf(2, "Finished successfully\n"); return (error); +} + +/* + * Times out for s seconds. + */ +void +cvsup_timeout(int s) +{ + time_t now = time(0); + now += s; + lprintf(-1, "Will retry at %s", ctime(&now)); + sleep(s); + lprintf(-1, "Retrying\n"); } --- proto.h.orig Sun Jun 19 22:38:44 2005 +++ proto.h Sun Jun 19 22:38:53 2005 @@ -31,5 +31,6 @@ int auth_required; int cvsup_connect(struct config *); int cvsup_init(struct config *); +void cvsup_timeout(int); #endif /* !_PROTO_H_ */