[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

ftp patch to support Last-Modified HTTP header



I got bored of "ftp http://..."; not setting the right time on the file. Here is
a first attempt at using the Last-Modified header, if it exists, to set the
file time. No attempt is made to sanity check the date (in the future etc.),
should it ?

Can someone who understands the code tell me where the output file (out - except
when it's stdout) gets closed ? Is using "volatile int s, out" mean the file is
closed when the url_get function returns ? I can't recall this behaviour...

Comments ?

rgds,
--
Peter



Index: usr.bin/ftp/fetch.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.49
diff -u -r1.49 fetch.c
--- usr.bin/ftp/fetch.c	28 Feb 2004 20:08:38 -0000	1.49
+++ usr.bin/ftp/fetch.c	28 Jun 2004 09:18:07 -0000
@@ -49,6 +49,7 @@
 #include <sys/param.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
+#include <sys/time.h>
 
 #include <netinet/in.h>
 
@@ -65,6 +66,7 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 #include <unistd.h>
 #include <util.h>
 
@@ -102,6 +104,9 @@
 	const char *outfile;
 {
 	struct addrinfo hints, *res0, *res;
+	struct tm lastmodified;
+	struct timeval httptime[2];
+	time_t lmt;
 	int error;
 	int i, isftpurl, isfileurl, isredirect;
 	volatile int s, out;
@@ -430,6 +435,8 @@
 	free(buf);
 	filesize = -1;
 
+	lmt = time(NULL);
+
 	while (1) {
 		if ((buf = fparseln(fin, &len, NULL, "\0\0\0", 0)) == NULL) {
 			warn("Receiving HTTP reply");
@@ -467,9 +474,38 @@
 			if (buf)
 				free(buf);
 			return (rval);
+#define LASTMODIFIED "Last-Modified: "
+		} else if (strncasecmp(cp, LASTMODIFIED,
+		    sizeof(LASTMODIFIED) - 1) == 0) {
+			/*
+                         * Try to parse the Last-Modified: header
+                         * to get a time for the file. The formats
+                         * tried are the example historical formats
+                         * given in RFC2616 "3.3.1 Full Date":
+			 *
+			 *   Sun, 06 Nov 1994 08:49:37 GMT  ;
+			 *	RFC 822, updated by RFC 1123
+			 *   Sunday, 06-Nov-94 08:49:37 GMT ;
+			 *	RFC 850, obsoleted by RFC 1036
+			 *   Sun Nov  6 08:49:37 1994       ;
+			 *	ANSI C's asctime() format
+			 *
+			 */
+
+			cp += sizeof(LASTMODIFIED) - 1;
+
+			memset(&lastmodified, 0, sizeof(lastmodified));
+			if (strptime(cp, "%a, %d %b %Y %T", &lastmodified) ||
+			    strptime(cp, "%a, %d-%b-%y %T", &lastmodified) ||
+			    strptime(cp, "%a %b %d %T %Y", &lastmodified)) {
+				lmt = mktime(&lastmodified);
+			}
 		}
 	}
 
+	httptime[0].tv_sec = httptime[1].tv_sec = lmt;
+	httptime[0].tv_usec = httptime[1].tv_usec = 0;
+
 	/* Open the output file.  */
 	if (strcmp(savefile, "-") != 0) {
 		out = open(savefile, O_CREAT | O_WRONLY | O_TRUNC, 0666);
@@ -559,6 +595,9 @@
 	if (proxy)
 		free(proxy);
 	free(line);
+	if (strcmp(savefile, "-") != 0) {
+		utimes(savefile, httptime);
+	}
 	return (rval);
 }