diff options
author | murray <murray@FreeBSD.org> | 2008-12-15 08:27:44 +0000 |
---|---|---|
committer | murray <murray@FreeBSD.org> | 2008-12-15 08:27:44 +0000 |
commit | 72a890ccd7d1c4fd04c561303e0ad5e45a6a4aaa (patch) | |
tree | 9ece849067a9d612c3bf00d2dd2a07b33b383a74 /usr.bin | |
parent | 3475c71ce83c2101fd0d42512193048affde82cc (diff) | |
download | FreeBSD-src-72a890ccd7d1c4fd04c561303e0ad5e45a6a4aaa.zip FreeBSD-src-72a890ccd7d1c4fd04c561303e0ad5e45a6a4aaa.tar.gz |
Add support for HTTP 1.1 If-Modified-Since behavior.
fetch(1) accepts a new argument -i <file> that if specified will cause
the file to be downloaded only if it is more recent than the mtime of
<file>.
libfetch(3) accepts the mtime in the url structure and a flag to
indicate when this behavior is desired.
PR: bin/87841
Submitted by: Jukka A. Ukkonen <jau@iki.fi> (partially)
Reviewed by: des, ru
MFC after: 3 weeks
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/fetch/fetch.1 | 16 | ||||
-rw-r--r-- | usr.bin/fetch/fetch.c | 29 |
2 files changed, 40 insertions, 5 deletions
diff --git a/usr.bin/fetch/fetch.1 b/usr.bin/fetch/fetch.1 index f7694f7..0dbbc0b 100644 --- a/usr.bin/fetch/fetch.1 +++ b/usr.bin/fetch/fetch.1 @@ -29,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 11, 2003 +.Dd December 14, 2008 .Dt FETCH 1 .Os .Sh NAME @@ -39,6 +39,7 @@ .Nm .Op Fl 146AadFlMmnPpqRrsUv .Op Fl B Ar bytes +.Op Fl i Ar file .Op Fl N Ar file .Op Fl o Ar file .Op Fl S Ar bytes @@ -48,6 +49,7 @@ .Nm .Op Fl 146AadFlMmnPpqRrsUv .Op Fl B Ar bytes +.Op Fl i Ar file .Op Fl N Ar file .Op Fl o Ar file .Op Fl S Ar bytes @@ -116,6 +118,12 @@ The file to retrieve is located on the host .Ar host . This option is deprecated and is provided for backward compatibility only. +.It Fl i Ar file +If-Modified-Since mode: the remote file will only be retrieved if it +is newer than +.Ar file +on the local host. +(HTTP only) .It Fl l If the target is a file-scheme URL, make a symbolic link to the target rather than trying to copy it. @@ -249,6 +257,12 @@ If multiple URLs are listed on the command line, .Nm will attempt to retrieve each one of them in turn, and will return zero only if they were all successfully retrieved. +.Pp +If the +.Fl i +argument is used and the remote file is not newer than the +specified file then the command will still return success, +although no file is transferred. .Sh SEE ALSO .Xr fetch 3 .Sh HISTORY diff --git a/usr.bin/fetch/fetch.c b/usr.bin/fetch/fetch.c index e71e821..eda8048 100644 --- a/usr.bin/fetch/fetch.c +++ b/usr.bin/fetch/fetch.c @@ -60,6 +60,8 @@ int d_flag; /* -d: direct connection */ int F_flag; /* -F: restart without checking mtime */ char *f_filename; /* -f: file to fetch */ char *h_hostname; /* -h: host to fetch from */ +int i_flag; /* -i: specify input file for mtime comparison */ +char *i_filename; /* name of input file */ int l_flag; /* -l: link rather than copy file: URLs */ int m_flag; /* -[Mm]: mirror mode */ char *N_filename; /* -N: netrc file name */ @@ -382,6 +384,14 @@ fetch(char *URL, const char *path) if (A_flag) strcat(flags, "A"); timeout = T_secs ? T_secs : http_timeout; + if (i_flag) { + if (stat(i_filename, &sb)) { + warn("%s: stat()", i_filename); + goto failure; + } + url->ims_time = sb.st_mtime; + strcat(flags, "i"); + } } /* set the protocol timeout. */ @@ -449,7 +459,14 @@ fetch(char *URL, const char *path) goto signal; if (f == NULL) { warnx("%s: %s", URL, fetchLastErrString); - goto failure; + if (i_flag && strcmp(url->scheme, SCHEME_HTTP) == 0 + && fetchLastErrCode == FETCH_OK + && strcmp(fetchLastErrString, "Not Modified") == 0) { + /* HTTP Not Modified Response, return OK. */ + r = 0; + goto done; + } else + goto failure; } if (sigint) goto signal; @@ -713,9 +730,9 @@ usage(void) { 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] URL ...", +" [-T seconds] [-w seconds] [-i file] URL ...", " fetch [-146AadFlMmnPpqRrsUv] [-B bytes] [-N file] [-o file] [-S bytes]", -" [-T seconds] [-w seconds] -h host -f file [-c dir]"); +" [-T seconds] [-w seconds] [-i file] -h host -f file [-c dir]"); } @@ -732,7 +749,7 @@ main(int argc, char *argv[]) int c, e, r; while ((c = getopt(argc, argv, - "146AaB:bc:dFf:Hh:lMmN:nPpo:qRrS:sT:tUvw:")) != -1) + "146AaB:bc:dFf:Hh:i:lMmN:nPpo:qRrS:sT:tUvw:")) != -1) switch (c) { case '1': once_flag = 1; @@ -777,6 +794,10 @@ main(int argc, char *argv[]) case 'h': h_hostname = optarg; break; + case 'i': + i_flag = 1; + i_filename = optarg; + break; case 'l': l_flag = 1; break; |