Hi all,

My morning routine consists of downloading the latest snapshot files and
running the upgrade.  To avoid wasting bandwidth and time, I check the
local modification time of INSTALL.amd64, fetch the remote one and check
if the modification time has changed.

A few days ago, the mirror I use had issues with the ftpd.  I quickly
switched the ftp:// to http:// and continued with my routine.  By doing
so, I noticed that when running ftp(1) on ftp links, it does preserve
the modification time.  But for http or https links, the modification
time is ignored.

I noticed the 'preserve' option is enabled by default, even when using
the auto-fetch feature.  I find this behaviour a bit inconsistent and
unintuitive, seeing it won't let the user specify whether or not the
preserve option should be enabled.  Yet, it behaves differently
depending on what protocol we use to fetch the file.

The patch below will use the Last-Modified header in order to set the
modification time for http or https links.  I also added, what to me
looked like a missing "\n" on the error message in ftp.c.

An alternative solution might be to have the preserve option disabled
by default when auto-fetching files.


Jesper Wallin


Index: fetch.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.163
diff -u -p -r1.163 fetch.c
--- fetch.c     7 Mar 2017 08:00:23 -0000       1.163
+++ fetch.c     22 Sep 2017 19:52:49 -0000
@@ -210,6 +210,7 @@ url_get(const char *origline, const char
        int status;
        int save_errno;
        const size_t buflen = 128 * 1024;
+       time_t mtime = -1;
 
        direction = "received";
 
@@ -860,6 +861,12 @@ noslash:
                        if (restart_point)
                                filesize += restart_point;
 #endif /* !SMALL */
+#define LASTMOD "Last-Modified: "
+               } else if (strncasecmp(cp, LASTMOD, sizeof(LASTMOD) - 1) == 0) {
+                       struct tm tm;
+                       cp += sizeof(LASTMOD) - 1;
+                       if (strptime(cp, "%a, %d %b %Y %T %z", &tm) != NULL)
+                               mtime = mktime(&tm);
 #define LOCATION "Location: "
                } else if (isredirect &&
                    strncasecmp(cp, LOCATION, sizeof(LOCATION) - 1) == 0) {
@@ -1043,8 +1050,22 @@ cleanup_url_get:
                fclose(fin);
        else if (s != -1)
                close(s);
-       if (out >= 0 && out != fileno(stdout))
+       if (out >= 0 && out != fileno(stdout)) {
+
+               if (mtime != -1) {
+                       struct timeval tv[2];
+                       tv[0].tv_sec = time(NULL);
+                       tv[0].tv_usec = tv[1].tv_usec = 0;
+                       tv[1].tv_sec = mtime;
+
+                       if (futimes(out, tv) == -1)
+                               fprintf(ttyout,
+                               "Can't change modification time on %s to %s\n",
+                                   savefile, asctime(localtime(&mtime)));
+               }
+
                close(out);
+       }
        free(buf);
        free(proxyhost);
        free(proxyurl);
Index: ftp.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/ftp.c,v
retrieving revision 1.100
diff -u -p -r1.100 ftp.c
--- ftp.c       22 Aug 2016 16:27:00 -0000      1.100
+++ ftp.c       22 Sep 2017 19:52:50 -0000
@@ -1217,7 +1217,7 @@ break2:
                                ut.modtime = mtime;
                                if (utime(local, &ut) == -1)
                                        fprintf(ttyout,
-                               "Can't change modification time on %s to %s",
+                               "Can't change modification time on %s to %s\n",
                                            local, asctime(localtime(&mtime)));
                        }
                }

Reply via email to