To make stable tests I'm using --owner --group and --mtime, and --mtime is fiddly because it parses a choose-your-own-adventure date format, and since we recently taught "date" to do that I thought maybe that should move into lib.
I was doing touch -t 198001010101 but tar has a builtin --mtime override, "mkdir" and "touch" are separate operations, and the reproducible build people are probably gonna want to do what I'm doing for the tests, so... Implementing --mtime with generic lib/ plumbing to try the date and touch formats in order and autodetect the format! The _problem_ is, the formats date currently checks are, in order: "%F %T", "%F %H:%M", "%F", "%H:%M:%S", "%H:%M" And then a hardcoded fallback to mmddhhmm[[cc]yy]. But the touch formats are: -d "%FT%T", "%F %T" -t "%m%d%H%M", "%y%m%d%H%M", "%C%y%m%d%H%M" If I want to convert touch -t 198001010101 to --mtime 198001010101 (and not have to recalculate the sha1sums), it needs to detect that 12 digits is a valid timestamp, but date ends with optional CC YY and touch _starts_ with optional CC YY... Wait, is that actually what posix says to do? http://pubs.opengroup.org/onlinepubs/9699919799/utilities/touch.html -t time Use the specified time instead of the current time. The option-argument shall be a decimal number of the form: [[CC]YY]MMDDhhmm[.SS] http://pubs.opengroup.org/onlinepubs/9699919799/utilities/date.html mmddhhmm[[cc]yy] Attempt to set the system date and time from the value given in the operand. This is only possible if the user has appropriate privileges and the system permits the setting of the system date and time. The first mm is the month (number); dd is the day (number); hh is the hour (number, 24-hour system); the second mm is the minute (number); cc is the century and is the first two digits of the year (this is optional); yy is the last two digits of the year and is optional. If century is not specified, then values in the range [69,99] shall refer to years 1969 to 1999 inclusive, and values in the range [00,68] shall refer to years 2000 to 2068 inclusive. The current year is the default if yy is omitted. [Option End] Ablative year at the _start_ vs ablative year at the _end. Grrrrr. What does the gnu/dammit tar do here, anyway? https://www.gnu.org/software/tar/manual/html_section/tar_63.html#SEC129 8 digits is treated as: yyyymmdd. Oh bravo. NEITHER of the two posix options. What does it do with... $ tar c hello.c --mtime 010101011980 tar: Substituting 1969-12-31 18:00 for unknown date format ‘010101011980’ $ tar c hello.c --mtime 198001010101 | hd 00000080 30 30 30 30 33 36 30 00 80 00 00 00 00 02 38 39 |0000360.......89| 00000090 4a 9f c9 60 30 31 32 35 31 36 00 20 30 00 00 00 |J..`012516. 0...| Ha, my "generic write out of the binary format when the field's too big" is _also_ what they do. $ python -c "print 0x238394a9fc960" 624768669698400 Ok, they didn't get it remotely right _and_ didn't treat the long unrecognized number as unixtime so I haven't got a clue what they're doing there... Aha! But "tar c hello.c --mtime @12345" accepts unixtime with the @ syntax! Right. Probably what I should do is move date.c's parse_formats() to lib, fluff it out a bit with "%FT%T" from touch -d and maybe "%m%d%H%M" from touch -t, and then have touch -d and date and mtime read that and barf on any format it doesn't recognize. Then touch -t can do what it's doing now and I can tar --mtime=@unixtime in the tests and have it also work in TEST_HOST. (I have no idea if busybox gets this right, and don't currently care.) [notices unsent message a day later...] Well I just factored out xparsedate() from date and I'm looking at reusing it in touch -d, and the problem is touch -t doesn't use it for the above reasons and I'll wind up with two codepaths doing the same thing which sucks. There's redundant nanosecond parsing here too. Hmmm... Rob _______________________________________________ Toybox mailing list [email protected] http://lists.landley.net/listinfo.cgi/toybox-landley.net
