ftp currently uses utime(3) to set the modification time on the retrieved 
file.  It set the access time on the file to the current time when doing 
so.  By converting this to use utimensat(), we can avoid the silly call 
to time(3) to get the current time for the atime by instead passing 
UTIME_NOW.

However, I _think_ ftp does this just because utime(3) has no way to set 
the modification time without also setting the access time and calling 
stat(2) just to get the current atime (and dealing with the possible error 
cases) wasn't worth it, so instead of setting the atime to the current 
time with UTIME_NOW, I propose leaving the atime unchanged with 
UTIME_OMIT.

Thoughts?  oks?


Philip Guenther


Index: ftp.c
===================================================================
RCS file: /data/src/openbsd/src/usr.bin/ftp/ftp.c,v
retrieving revision 1.105
diff -u -p -r1.105 ftp.c
--- ftp.c       28 Jun 2019 13:35:01 -0000      1.105
+++ ftp.c       14 Oct 2019 01:32:56 -0000
@@ -72,6 +72,7 @@
 #include <ctype.h>
 #include <err.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <netdb.h>
 #include <poll.h>
 #include <stdarg.h>
@@ -79,7 +80,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <utime.h>
 
 #include "ftp_var.h"
 
@@ -1211,11 +1211,12 @@ break2:
                if (preserve && (closefunc == fclose)) {
                        mtime = remotemodtime(remote, 0);
                        if (mtime != -1) {
-                               struct utimbuf ut;
+                               struct timespec times[2];
 
-                               ut.actime = time(NULL);
-                               ut.modtime = mtime;
-                               if (utime(local, &ut) == -1)
+                               times[0].tv_nsec = UTIME_OMIT;
+                               times[1].tv_sec = mtime;
+                               times[1].tv_nsec = 0;
+                               if (utimensat(AT_FDCWD, local, times, 0) == -1)
                                        fprintf(ttyout,
                                "Can't change modification time on %s to %s",
                                            local, asctime(localtime(&mtime)));

Reply via email to