summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorMurray Stokely <murray@FreeBSD.org>2009-01-09 03:42:41 +0000
committerMurray Stokely <murray@FreeBSD.org>2009-01-09 03:42:41 +0000
commit6ae463b6f751785137d82ee25f13c9e106b0149d (patch)
treeaa8ab715cf5f538cecc62161746565943a6affda /usr.bin
parent55e2d46c54bc6ebb32b63c779e6239c12e888c0d (diff)
Notes
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/fetch/fetch.134
-rw-r--r--usr.bin/fetch/fetch.c45
2 files changed, 60 insertions, 19 deletions
diff --git a/usr.bin/fetch/fetch.1 b/usr.bin/fetch/fetch.1
index 3922db581930..0dbbc0b04f15 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
@@ -37,17 +37,25 @@
.Nd retrieve a file by Uniform Resource Locator
.Sh SYNOPSIS
.Nm
-.Op Fl 146AFMPRUadlmnpqrsv
+.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
.Op Fl T Ar seconds
+.Op Fl w Ar seconds
+.Ar URL ...
+.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
+.Op Fl T Ar seconds
.Op Fl w Ar seconds
-.Op Fl h Ar host
-.Op Fl c Ar dir
-.Op Fl f Ar file
-.Op Ar URL ...
+.Fl h Ar host Fl f Ar file Oo Fl c Ar dir Oc
.Sh DESCRIPTION
The
.Nm
@@ -59,7 +67,7 @@ command line.
.Pp
The following options are available:
.Bl -tag -width Fl
-.It Fl \&1
+.It Fl 1
Stop and return exit code 0 at the first successfully retrieved file.
.It Fl 4
Forces
@@ -110,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.
@@ -243,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 3dc276aaf719..1bf7e02ddfeb 100644
--- a/usr.bin/fetch/fetch.c
+++ b/usr.bin/fetch/fetch.c
@@ -42,7 +42,6 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sysexits.h>
#include <termios.h>
#include <unistd.h>
@@ -60,6 +59,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 */
@@ -381,6 +382,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. */
@@ -448,7 +457,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;
@@ -710,10 +726,11 @@ fetch(char *URL, const char *path)
static void
usage(void)
{
- fprintf(stderr, "%s\n%s\n%s\n",
- "usage: fetch [-146AFMPRUadlmnpqrsv] [-N netrc] [-o outputfile]",
- " [-S bytes] [-B bytes] [-T seconds] [-w seconds]",
- " [-h host -f file [-c dir] | URL ...]");
+ 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 ...",
+" fetch [-146AadFlMmnPpqRrsUv] [-B bytes] [-N file] [-o file] [-S bytes]",
+" [-T seconds] [-w seconds] [-i file] -h host -f file [-c dir]");
}
@@ -730,7 +747,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;
@@ -775,6 +792,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;
@@ -842,7 +863,7 @@ main(int argc, char *argv[])
break;
default:
usage();
- exit(EX_USAGE);
+ exit(1);
}
argc -= optind;
@@ -851,7 +872,7 @@ main(int argc, char *argv[])
if (h_hostname || f_filename || c_dirname) {
if (!h_hostname || !f_filename || argc) {
usage();
- exit(EX_USAGE);
+ exit(1);
}
/* XXX this is a hack. */
if (strcspn(h_hostname, "@:/") != strlen(h_hostname))
@@ -864,7 +885,7 @@ main(int argc, char *argv[])
if (!argc) {
usage();
- exit(EX_USAGE);
+ exit(1);
}
/* allocate buffer */
@@ -905,10 +926,10 @@ main(int argc, char *argv[])
} else if (stat(o_filename, &sb) == -1) {
if (errno == ENOENT) {
if (argc > 1)
- errx(EX_USAGE, "%s is not a directory",
+ errx(1, "%s is not a directory",
o_filename);
} else {
- err(EX_IOERR, "%s", o_filename);
+ err(1, "%s", o_filename);
}
} else {
if (sb.st_mode & S_IFDIR)