[Toybox] tar tests.

Rob Landley rob at landley.net
Sun Mar 24 16:18:26 PDT 2019


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


More information about the Toybox mailing list