bin/131427: [patch] Add to fetch(1) an ability to limit a number of auto-retries

Alexander Gromnitsky alexander.gromnitsky at gmail.com
Thu Feb 5 11:20:04 PST 2009


>Number:         131427
>Category:       bin
>Synopsis:       [patch] Add to fetch(1) an ability to limit a number of auto-retries
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Feb 05 19:20:03 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator:     Alexander Gromnitsky
>Release:        FreeBSD 8.0-CURRENT i386
>Organization:
>Environment:
System: FreeBSD fbsdcurrent.medieval 8.0-CURRENT FreeBSD 8.0-CURRENT #0: Thu Feb 5 17:12:48 EET 2009 root at fbsdcurrent.medieval:/usr/obj/usr/src/sys/GENERIC i386


	
>Description:
fetch(1) has got a special `-a' option that allows automatically
retrying a transfer upon soft failures. But if, for example, a server
returns HTTP error "403 Permission Denied", fetch(1) will loop forever
trying to repeat the request.

It's useful to have an opportunity to control such behaviour.

>How-To-Repeat:
% fetch -a http://foobar.com
fetch: http://foobar.com: Forbidden
fetch: http://foobar.com: Forbidden
fetch: http://foobar.com: Forbidden
fetch: http://foobar.com: Forbidden
fetch: http://foobar.com: Forbidden
^Cfetch: transfer interrupted

With a new `-e' option we can limit a number of retries:

% fetch -e 2 http://foobar.com
fetch: http://foobar.com: Forbidden
fetch: http://foobar.com: Forbidden
fetch: http://foobar.com: Forbidden

>Fix:

	

--- fetch.patch begins here ---
Only in fetch: fetch
diff -ur fetch.orig/fetch.1 fetch/fetch.1
--- fetch.orig/fetch.1	2008-12-15 10:27:44.000000000 +0200
+++ fetch/fetch.1	2009-02-04 13:33:38.000000000 +0200
@@ -45,6 +45,7 @@
 .Op Fl S Ar bytes
 .Op Fl T Ar seconds
 .Op Fl w Ar seconds
+.Op Fl e Ar number
 .Ar URL ...
 .Nm
 .Op Fl 146AadFlMmnPpqRrsUv
@@ -55,6 +56,7 @@
 .Op Fl S Ar bytes
 .Op Fl T Ar seconds
 .Op Fl w Ar seconds
+.Op Fl e Ar number
 .Fl h Ar host Fl f Ar file Oo Fl c Ar dir Oc
 .Sh DESCRIPTION
 The
@@ -83,6 +85,10 @@
 error when the requested object does not exist.
 .It Fl a
 Automatically retry the transfer upon soft failures.
+.It Fl e Ar number
+Set number of auto-retries, -1 for infinite retrying (the
+default). Implies
+.Fl a .
 .It Fl B Ar bytes
 Specify the read buffer size in bytes.
 The default is 4096 bytes.
Only in fetch: fetch.1.gz
diff -ur fetch.orig/fetch.c fetch/fetch.c
--- fetch.orig/fetch.c	2009-01-17 15:34:56.000000000 +0200
+++ fetch/fetch.c	2009-02-04 13:35:50.000000000 +0200
@@ -53,6 +53,7 @@
 /* Option flags */
 int	 A_flag;	/*    -A: do not follow 302 redirects */
 int	 a_flag;	/*    -a: auto retry */
+int	 a_flag_tries = -1;	/*    -e: number of retries, -1 for infinite */
 off_t	 B_size;	/*    -B: buffer size */
 int	 b_flag;	/*!   -b: workaround TCP bug */
 char    *c_dirname;	/*    -c: remote directory */
@@ -730,9 +731,9 @@
 {
 	fprintf(stderr, "%s\n%s\n%s\n%s\n",
 "usage: fetch [-146AadFlMmnPpqRrsUv] [-B bytes] [-N file] [-o file] [-S bytes]",
-"       [-T seconds] [-w seconds] [-i file] URL ...",
+"       [-T seconds] [-w seconds] [-e number] [-i file] URL ...",
 "       fetch [-146AadFlMmnPpqRrsUv] [-B bytes] [-N file] [-o file] [-S bytes]",
-"       [-T seconds] [-w seconds] [-i file] -h host -f file [-c dir]");
+"       [-T seconds] [-w seconds] [-e number] [-i file] -h host -f file [-c dir]");
 }
 
 
@@ -749,7 +750,7 @@
 	int c, e, r;
 
 	while ((c = getopt(argc, argv,
-	    "146AaB:bc:dFf:Hh:i:lMmN:nPpo:qRrS:sT:tUvw:")) != -1)
+	    "146AaB:bc:dFf:Hh:i:lMmN:nPpo:qRrS:sT:tUvw:e:")) != -1)
 		switch (c) {
 		case '1':
 			once_flag = 1;
@@ -766,6 +767,12 @@
 		case 'a':
 			a_flag = 1;
 			break;
+		case 'e':
+			a_flag = 1;
+			a_flag_tries = strtol(optarg, &end, 10);
+			if (*optarg == '\0' || *end != '\0')
+				errx(1, "invalid number (%s)", optarg);
+			break;
 		case 'B':
 			B_size = (off_t)strtol(optarg, &end, 10);
 			if (*optarg == '\0' || *end != '\0')
@@ -996,8 +1003,16 @@
 					    "before retrying\n", w_secs);
 				if (w_secs)
 					sleep(w_secs);
-				if (a_flag)
+
+				if (a_flag && a_flag_tries > 0) {
+					if (v_level >= 2)
+						warnx("retries left: %d", a_flag_tries);
+					--a_flag_tries;
 					continue;
+				}
+
+				/* user wants to retry forever */
+				if (a_flag && a_flag_tries < 0) continue;
 			}
 		}
 
Only in fetch: fetch.o
--- fetch.patch ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list