Download raw body.
ftp(1): parse fractional seconds in MDTM responses
On 2026-02-12 05:43, Philip Guenther wrote:
This doesn't correctly handle more than 9 digits after the decimal
point.
Using strtol() should be avoided since supporting a "timestamp" of
"20260212044126. -34" is not useful.
ok.
the new diff uses manual parsing.
also, i can't test the code and I had to generate the diff
in a github codespace on my phone.
--- util.c 2026-02-12 17:23:52.915431814 +0000
+++ utility.c 2026-02-12 18:06:29.259810577 +0000
@@ -602,16 +602,15 @@
/*
* 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 result;
+ int ocode, overbose;
+
overbose = verbose;
ocode = code;
- rtime = -1;
+ result.tv_sec = -1;
#ifndef SMALL
if (!debug)
#endif /* !SMALL */
@@ -619,14 +618,15 @@
if (command("MDTM %s", file) == COMPLETE) {
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 */
while (!isspace((unsigned char)*timestr))
timestr++;
@@ -649,15 +649,40 @@
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;
+ if (nsec < 0 || nsec >= 1000000000L) /*
Do I need this? */
+ nsec = 0;
+ }
+ } else
+ nsec = 0;
+
+ result.tv_sec = mktime(&timebuf);
+ result.tv_nsec = nsec;
+ if (result.tv_sec == -1 && (noisy
#ifndef SMALL
|| debug
#endif /* !SMALL */
))
fprintf(ttyout, "Can't convert %s to a time.\n",
reply_string);
else
- rtime += timebuf.tm_gmtoff; /* conv. local
-> GMT */
+ result.tv_sec += timebuf.tm_gmtoff; /* conv.
local -> GMT */
} else if (noisy
#ifndef SMALL
&& !debug
@@ -667,9 +692,9 @@
fputc('\n', ttyout);
}
verbose = overbose;
- if (rtime == -1)
+ if (result.tv_sec == -1)
code = ocode;
- return (rtime);
+ return (result);
}
/*
is this in the right direction?
my bad if the formatting is off
ftp(1): parse fractional seconds in MDTM responses