Sync fetch(1) with FreeBSD.
authorSascha Wildner <saw@online.de>
Sun, 10 May 2009 01:23:44 +0000 (03:23 +0200)
committerSascha Wildner <saw@online.de>
Sun, 10 May 2009 11:40:34 +0000 (13:40 +0200)
usr.bin/fetch/fetch.1
usr.bin/fetch/fetch.c

index 68d4a17..e8da991 100644 (file)
 .\" (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
@@ -60,7 +68,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
@@ -111,6 +119,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.
@@ -213,19 +227,29 @@ message.
 .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
@@ -234,6 +258,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
index 817219f..a3f32b0 100644 (file)
@@ -1,5 +1,5 @@
 /*-
- * 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
@@ -25,7 +25,7 @@
  * (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 */
@@ -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 */
@@ -74,7 +76,7 @@ int    R_flag;        /*    -R: don't delete partially transferred files */
 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 */
@@ -87,8 +89,8 @@ int    sigalrm;       /* SIGALRM received */
 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 */
 
 
@@ -364,7 +366,7 @@ fetch(char *URL, const char *path)
        }
 
        /* 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)
@@ -375,12 +377,21 @@ fetch(char *URL, const char *path)
        }
 
        /* 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. */
@@ -448,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;
@@ -714,10 +732,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]");
 }
 
 
@@ -734,7 +753,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;
@@ -779,6 +798,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;
@@ -846,7 +869,7 @@ main(int argc, char *argv[])
                        break;
                default:
                        usage();
-                       exit(EX_USAGE);
+                       exit(1);
                }
 
        argc -= optind;
@@ -855,7 +878,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))
@@ -868,7 +891,7 @@ main(int argc, char *argv[])
 
        if (!argc) {
                usage();
-               exit(EX_USAGE);
+               exit(1);
        }
 
        /* allocate buffer */
@@ -909,10 +932,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)