.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $FreeBSD: src/usr.bin/fetch/fetch.1,v 1.67 2006/04/22 03:04:24 jkoshy Exp $
+.\" $FreeBSD: src/usr.bin/fetch/fetch.1,v 1.70 2008/12/15 08:27:44 murray Exp $
.\" $DragonFly: src/usr.bin/fetch/fetch.1,v 1.4 2007/08/05 21:48:12 swildner Exp $
.\"
-.Dd August 5, 2007
+.Dd May 10, 2009
.Dt FETCH 1
.Os
.Sh NAME
.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
.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
.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.
.Sh ENVIRONMENT
.Bl -tag -width HTTP_TIMEOUT
.It Ev FTP_TIMEOUT
-maximum time, in seconds, to wait before aborting an FTP connection.
+Maximum time, in seconds, to wait before aborting an FTP connection.
.It Ev HTTP_TIMEOUT
-maximum time, in seconds, to wait before aborting an HTTP connection.
+Maximum time, in seconds, to wait before aborting an HTTP connection.
.El
.Pp
-All environment variables mentioned in the documentation for the
-.Xr fetch 3
-library are supported.
-A number of these are quite important to the proper operation of
-.Nm ;
-you are strongly encouraged to read
+See
.Xr fetch 3
-as well.
+for a description of additional environment variables, including
+.Ev FETCH_BIND_ADDRESS ,
+.Ev FTP_LOGIN ,
+.Ev FTP_PASSIVE_MODE ,
+.Ev FTP_PASSWORD ,
+.Ev FTP_PROXY ,
+.Ev ftp_proxy ,
+.Ev HTTP_AUTH ,
+.Ev HTTP_PROXY ,
+.Ev http_proxy ,
+.Ev HTTP_PROXY_AUTH ,
+.Ev HTTP_REFERER ,
+.Ev HTTP_USER_AGENT ,
+.Ev NETRC ,
+.Ev NO_PROXY and
+.Ev no_proxy .
.Sh EXIT STATUS
The
.Nm
.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
/*-
- * Copyright (c) 2000-2004 Dag-Erling Coïdan Smørgrav
+ * Copyright (c) 2000-2004 Dag-Erling Coïdan Smørgrav
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $FreeBSD: src/usr.bin/fetch/fetch.c,v 1.78 2006/11/10 22:05:41 des Exp $
+ * $FreeBSD: src/usr.bin/fetch/fetch.c,v 1.84 2009/01/17 13:34:56 des Exp $
* $DragonFly: src/usr.bin/fetch/fetch.c,v 1.8 2007/08/05 21:48:12 swildner Exp $
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sysexits.h>
#include <termios.h>
#include <unistd.h>
#include <fetch.h>
#define MINBUFSIZE 4096
+#define TIMEOUT 120
/* Option flags */
int A_flag; /* -A: do not follow 302 redirects */
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 */
int r_flag; /* -r: restart previously interrupted transfer */
off_t S_size; /* -S: require size to match */
int s_flag; /* -s: show size, don't fetch */
-long T_secs = 120; /* -T: transfer timeout in seconds */
+long T_secs; /* -T: transfer timeout in seconds */
int t_flag; /*! -t: workaround TCP bug */
int U_flag; /* -U: do not use high ports */
int v_level = 1; /* -v: verbosity level */
int siginfo; /* SIGINFO received */
int sigint; /* SIGINT received */
-long ftp_timeout; /* default timeout for FTP transfers */
-long http_timeout; /* default timeout for HTTP transfers */
+long ftp_timeout = TIMEOUT; /* default timeout for FTP transfers */
+long http_timeout = TIMEOUT; /* default timeout for HTTP transfers */
char *buf; /* transfer buffer */
}
/* FTP specific flags */
- if (strcmp(url->scheme, "ftp") == 0) {
+ if (strcmp(url->scheme, SCHEME_FTP) == 0) {
if (p_flag)
strcat(flags, "p");
if (d_flag)
}
/* HTTP specific flags */
- if (strcmp(url->scheme, "http") == 0) {
+ if (strcmp(url->scheme, SCHEME_HTTP) == 0 ||
+ strcmp(url->scheme, SCHEME_HTTPS) == 0) {
if (d_flag)
strcat(flags, "d");
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. */
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;
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]");
}
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;
case 'h':
h_hostname = optarg;
break;
+ case 'i':
+ i_flag = 1;
+ i_filename = optarg;
+ break;
case 'l':
l_flag = 1;
break;
break;
default:
usage();
- exit(EX_USAGE);
+ exit(1);
}
argc -= optind;
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))
if (!argc) {
usage();
- exit(EX_USAGE);
+ exit(1);
}
/* allocate buffer */
} 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)