hello,

i updated the patch, to actually show the parsed fractional seconds.

here is the format it will show in (timestamp not date)

06:00:00.PARSED_FRACTIONAL_SECONDS

here is the diff:

Index: cmds.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/cmds.c,v
diff -u -p -u -p -r1.85 cmds.c
--- cmds.c      8 Mar 2023 04:43:11 -0000       1.85
+++ cmds.c      18 Feb 2026 22:48:04 -0000
@@ -1587,19 +1587,39 @@ sizecmd(int argc, char *argv[])
 void
 modtime(int argc, char *argv[])
 {
-       time_t mtime;
-
+               struct timespec mtime;
        if ((argc < 2 && !another(&argc, &argv, "file")) || argc > 2) {
                fprintf(ttyout, "usage: %s file\n", argv[0]);
                code = -1;
                return;
        }
-       mtime = remotemodtime(argv[1], 1);
-       if (mtime != -1)
-               fprintf(ttyout, "%s\t%s", argv[1], asctime(localtime(&mtime)));
-       code = mtime;
-}
+        mtime = remotemodtime(argv[1], 1);
+               if (mtime.tv_sec != -1) {
+               char timebuf[64];
+               struct tm *tm;
+
+                tm = localtime(&mtime.tv_sec);
+                strftime(timebuf, sizeof(timebuf), "%a %b %d %H:%M:%S", tm);

+                if (mtime.tv_nsec == 0) {
+                       fprintf(ttyout, "%s\t%s %d\n", argv[1], timebuf,
+                                       tm->tm_year + 1900);
+                       } else {
+                        char nsbuf[16];
+                               char *end;
+
+                               snprintf(nsbuf, sizeof(nsbuf), "%09ld", 
mtime.tv_nsec);
+                               end = nsbuf + strlen(nsbuf) - 1;
+                               while (end > nsbuf && *end == '0')
+                                       end--;
+                               *(end + 1) = '\0';
+                               fprintf(ttyout, "%s\t%s.%s %d\n", argv[1], 
timebuf,
+                                       nsbuf, tm->tm_year + 1900);
+               }
+
+       }
+       code = mtime.tv_sec;
+}
 /*
  * Show status on remote machine
  */
Index: extern.h
===================================================================
RCS file: /cvs/src/usr.bin/ftp/extern.h,v
diff -u -p -u -p -r1.54 extern.h
--- extern.h    21 May 2024 05:00:48 -0000      1.54
+++ extern.h    18 Feb 2026 22:48:04 -0000
@@ -101,7 +101,7 @@ void        recvrequest(const char *, const cha
            const char *, int, int);
 char   *remglob(char **, int, char **);
 off_t  remotesize(const char *, int);
-time_t remotemodtime(const char *, int);
+struct  timespec remotemodtime(const char *, int);
 void   reset(int, char **);
 void   rmthelp(int, char **);
 void   sethash(int, char **);
Index: ftp.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/ftp.c,v
diff -u -p -u -p -r1.109 ftp.c
--- ftp.c       8 Mar 2023 04:43:11 -0000       1.109
+++ ftp.c       18 Feb 2026 22:48:04 -0000
@@ -1204,7 +1204,7 @@ break2:
                if (bytes > 0)
                        ptransfer(0);
                if (preserve && (closefunc == fclose)) {
-                       mtime = remotemodtime(remote, 0);
+                               mtime = remotemodtime(remote, 0).tv_sec;
                        if (mtime != -1) {
                                struct timespec times[2];

Index: small.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/small.c,v
diff -u -p -u -p -r1.13 small.c
--- small.c     8 Mar 2023 04:43:11 -0000       1.13
+++ small.c     18 Feb 2026 22:48:04 -0000
@@ -269,7 +269,7 @@ usage:
                        if (ret == 0) {
                                time_t mtime;

-                               mtime = remotemodtime(argv[1], 0);
+                                mtime = remotemodtime(argv[1], 0).tv_sec;
                                if (mtime == -1)
                                        goto freegetit;
                                if (stbuf.st_mtime >= mtime) {
Index: util.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/util.c,v
diff -u -p -u -p -r1.99 util.c
--- util.c      21 Dec 2025 07:29:03 -0000      1.99
+++ util.c      18 Feb 2026 22:48:04 -0000
@@ -602,29 +602,32 @@ remotesize(const char *file, int noisy)
 /*
  * determine last modification time (in GMT) of remote file
  */
-time_t
+struct timespec
 remotemodtime(const char *file, int noisy)
 {
-       int overbose;
-       time_t rtime;
-       int ocode;
+       struct timespec rtime;
+       int ocode, overbose;

-       overbose = verbose;
-       ocode = code;
-       rtime = -1;
+       overbose = verbose;
+       ocode = code;
+       rtime.tv_sec = -1;
+       rtime.tv_nsec = 0;
 #ifndef SMALL
        if (!debug)
 #endif /* !SMALL */
                verbose = -1;
        if (command("MDTM %s", file) == COMPLETE) {
-               struct tm timebuf;
-               int yy, mo, day, hour, min, sec;
+                       fprintf(ttyout, "DEBUG: reply_string = '%s'\n", 
reply_string);
+               struct tm timebuf;
+               int yy, mo, day, hour, min, sec;
+                       char *cp, *ep;
+                       long frac, nsec;
+                       int i, multiplier, num_digits;
                /*
                 * time-val = 14DIGIT [ "." 1*DIGIT ]
                 *              YYYYMMDDHHMMSS[.sss]
                 * mdtm-response = "213" SP time-val CRLF / error-response
                 */
-               /* TODO: parse .sss as well, use timespecs. */
                char *timestr = reply_string;

                /* Repair `19%02d' bug on server side */
@@ -649,15 +652,40 @@ remotemodtime(const char *file, int nois
                timebuf.tm_mon = mo - 1;
                timebuf.tm_year = yy - 1900;
                timebuf.tm_isdst = -1;
-               rtime = mktime(&timebuf);
-               if (rtime == -1 && (noisy
+
+               cp = strchr(reply_string, '.');
+               if (cp != NULL) {
+                      cp++;
+                      ep = cp;
+                      while (isdigit((unsigned char)*ep))
+                              ep++;
+                      num_digits = ep - cp;
+                      if (num_digits == 0 || num_digits > 9)
+                              nsec = 0;
+                      else {
+                              frac = 0;
+                               for (i = 0; i < num_digits; i++)
+                                       frac = frac * 10 + (cp[i] - '0');
+                               multiplier = 1;
+                               for (i = num_digits; i < 9; i++)
+                                       multiplier *= 10;
+                               nsec = frac * multiplier;
+                       }
+               } else
+                       nsec = 0;
+
+               rtime.tv_sec = mktime(&timebuf);
+               rtime.tv_nsec = nsec;
+               if (rtime.tv_sec == -1 && (noisy
 #ifndef SMALL
                    || debug
 #endif /* !SMALL */
                    ))
-                       fprintf(ttyout, "Can't convert %s to a time.\n", 
reply_string);
+                       fprintf(ttyout, "Can't convert %s to a time.\n",
+                           reply_string);
                else
-                       rtime += timebuf.tm_gmtoff;     /* conv. local -> GMT */
+                       /* conv. local -> GMT */
+                       rtime.tv_sec += timebuf.tm_gmtoff;
        } else if (noisy
 #ifndef SMALL
            && !debug
@@ -667,11 +695,10 @@ remotemodtime(const char *file, int nois
                fputc('\n', ttyout);
        }
        verbose = overbose;
-       if (rtime == -1)
+               if (rtime.tv_sec == -1)
                code = ocode;
        return (rtime);
 }
-
 /*
  * Ensure file is in or under dir.
  * Returns 1 if so, 0 if not (or an error occurred).

:wq ben

i also attached it if the formatting gets messed up.

although i still haven't tested on ramdisks

-ben
? cmds.d
? cmdtab.d
? complete.d
? cookie.d
? domacro.d
? fetch.d
? ftp
? ftp.d
? list.d
? main.d
? ruserpass.d
? small.d
? stringlist.d
? util.d
Index: cmds.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/cmds.c,v
diff -u -p -u -p -r1.85 cmds.c
--- cmds.c      8 Mar 2023 04:43:11 -0000       1.85
+++ cmds.c      18 Feb 2026 22:48:04 -0000
@@ -1587,19 +1587,39 @@ sizecmd(int argc, char *argv[])
 void
 modtime(int argc, char *argv[])
 {
-       time_t mtime;
-
+               struct timespec mtime;
        if ((argc < 2 && !another(&argc, &argv, "file")) || argc > 2) {
                fprintf(ttyout, "usage: %s file\n", argv[0]);
                code = -1;
                return;
        }
-       mtime = remotemodtime(argv[1], 1);
-       if (mtime != -1)
-               fprintf(ttyout, "%s\t%s", argv[1], asctime(localtime(&mtime)));
-       code = mtime;
-}
+        mtime = remotemodtime(argv[1], 1);
+               if (mtime.tv_sec != -1) {
+               char timebuf[64];
+               struct tm *tm;
+
+                tm = localtime(&mtime.tv_sec);
+                strftime(timebuf, sizeof(timebuf), "%a %b %d %H:%M:%S", tm);
 
+                if (mtime.tv_nsec == 0) {
+                       fprintf(ttyout, "%s\t%s %d\n", argv[1], timebuf,
+                                       tm->tm_year + 1900);
+                       } else {
+                        char nsbuf[16];
+                               char *end;
+
+                               snprintf(nsbuf, sizeof(nsbuf), "%09ld", 
mtime.tv_nsec);
+                               end = nsbuf + strlen(nsbuf) - 1;
+                               while (end > nsbuf && *end == '0')
+                                       end--;
+                               *(end + 1) = '\0';
+                               fprintf(ttyout, "%s\t%s.%s %d\n", argv[1], 
timebuf,
+                                       nsbuf, tm->tm_year + 1900);
+               }
+
+       }
+       code = mtime.tv_sec;
+}
 /*
  * Show status on remote machine
  */
Index: extern.h
===================================================================
RCS file: /cvs/src/usr.bin/ftp/extern.h,v
diff -u -p -u -p -r1.54 extern.h
--- extern.h    21 May 2024 05:00:48 -0000      1.54
+++ extern.h    18 Feb 2026 22:48:04 -0000
@@ -101,7 +101,7 @@ void        recvrequest(const char *, const cha
            const char *, int, int);
 char   *remglob(char **, int, char **);
 off_t  remotesize(const char *, int);
-time_t remotemodtime(const char *, int);
+struct  timespec remotemodtime(const char *, int);
 void   reset(int, char **);
 void   rmthelp(int, char **);
 void   sethash(int, char **);
Index: ftp.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/ftp.c,v
diff -u -p -u -p -r1.109 ftp.c
--- ftp.c       8 Mar 2023 04:43:11 -0000       1.109
+++ ftp.c       18 Feb 2026 22:48:04 -0000
@@ -1204,7 +1204,7 @@ break2:
                if (bytes > 0)
                        ptransfer(0);
                if (preserve && (closefunc == fclose)) {
-                       mtime = remotemodtime(remote, 0);
+                               mtime = remotemodtime(remote, 0).tv_sec;
                        if (mtime != -1) {
                                struct timespec times[2];
 
Index: small.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/small.c,v
diff -u -p -u -p -r1.13 small.c
--- small.c     8 Mar 2023 04:43:11 -0000       1.13
+++ small.c     18 Feb 2026 22:48:04 -0000
@@ -269,7 +269,7 @@ usage:
                        if (ret == 0) {
                                time_t mtime;
 
-                               mtime = remotemodtime(argv[1], 0);
+                                mtime = remotemodtime(argv[1], 0).tv_sec;
                                if (mtime == -1)
                                        goto freegetit;
                                if (stbuf.st_mtime >= mtime) {
Index: util.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/util.c,v
diff -u -p -u -p -r1.99 util.c
--- util.c      21 Dec 2025 07:29:03 -0000      1.99
+++ util.c      18 Feb 2026 22:48:04 -0000
@@ -602,29 +602,32 @@ remotesize(const char *file, int noisy)
 /*
  * determine last modification time (in GMT) of remote file
  */
-time_t
+struct timespec
 remotemodtime(const char *file, int noisy)
 {
-       int overbose;
-       time_t rtime;
-       int ocode;
+       struct timespec rtime;
+       int ocode, overbose;
 
-       overbose = verbose;
-       ocode = code;
-       rtime = -1;
+       overbose = verbose;
+       ocode = code;
+       rtime.tv_sec = -1;
+       rtime.tv_nsec = 0;
 #ifndef SMALL
        if (!debug)
 #endif /* !SMALL */
                verbose = -1;
        if (command("MDTM %s", file) == COMPLETE) {
-               struct tm timebuf;
-               int yy, mo, day, hour, min, sec;
+                       fprintf(ttyout, "DEBUG: reply_string = '%s'\n", 
reply_string);
+               struct tm timebuf;
+               int yy, mo, day, hour, min, sec;
+                       char *cp, *ep;
+                       long frac, nsec;
+                       int i, multiplier, num_digits;
                /*
                 * time-val = 14DIGIT [ "." 1*DIGIT ]
                 *              YYYYMMDDHHMMSS[.sss]
                 * mdtm-response = "213" SP time-val CRLF / error-response
                 */
-               /* TODO: parse .sss as well, use timespecs. */
                char *timestr = reply_string;
 
                /* Repair `19%02d' bug on server side */
@@ -649,15 +652,40 @@ remotemodtime(const char *file, int nois
                timebuf.tm_mon = mo - 1;
                timebuf.tm_year = yy - 1900;
                timebuf.tm_isdst = -1;
-               rtime = mktime(&timebuf);
-               if (rtime == -1 && (noisy
+
+               cp = strchr(reply_string, '.');
+               if (cp != NULL) {
+                      cp++;
+                      ep = cp;
+                      while (isdigit((unsigned char)*ep))
+                              ep++;
+                      num_digits = ep - cp;
+                      if (num_digits == 0 || num_digits > 9)
+                              nsec = 0;
+                      else {
+                              frac = 0;
+                               for (i = 0; i < num_digits; i++)
+                                       frac = frac * 10 + (cp[i] - '0');
+                               multiplier = 1;
+                               for (i = num_digits; i < 9; i++)
+                                       multiplier *= 10;
+                               nsec = frac * multiplier;
+                       }
+               } else
+                       nsec = 0;
+
+               rtime.tv_sec = mktime(&timebuf);
+               rtime.tv_nsec = nsec;
+               if (rtime.tv_sec == -1 && (noisy
 #ifndef SMALL
                    || debug
 #endif /* !SMALL */
                    ))
-                       fprintf(ttyout, "Can't convert %s to a time.\n", 
reply_string);
+                       fprintf(ttyout, "Can't convert %s to a time.\n",
+                           reply_string);
                else
-                       rtime += timebuf.tm_gmtoff;     /* conv. local -> GMT */
+                       /* conv. local -> GMT */
+                       rtime.tv_sec += timebuf.tm_gmtoff;
        } else if (noisy
 #ifndef SMALL
            && !debug
@@ -667,11 +695,10 @@ remotemodtime(const char *file, int nois
                fputc('\n', ttyout);
        }
        verbose = overbose;
-       if (rtime == -1)
+               if (rtime.tv_sec == -1)
                code = ocode;
        return (rtime);
 }
-
 /*
  * Ensure file is in or under dir.
  * Returns 1 if so, 0 if not (or an error occurred).

Reply via email to