I'm using OpenBSD 7.0 GENERIC.MP#232 amd64.

OpenBSD's tar and pax seem to always think mtimes are zero when
extracting tar files created by OpenBSD's python3 (python-3.8.12).

These tar files have correct mtimes when opened by python3 itself or
read by gtar from ports. Similarly, Linux tar sees correct mtimes.

`file` claims the tar files are 'POSIX tar archive'.

OpenBSD's python2 doesn't seem to have this probelem - it creates tar
files that work correctly with OpenBSD's tar and pax.

When loading a python3-created tar file in python3, it says the format
is 2, which is tarfile.PAX_FORMAT, so i would have expected things
to work with tar and pax. Python-3.8 changed the default from
GNU_FORMAT to PAX_FORMAT
(https://docs.python.org/3/library/tarfile.html#tar-formats "Changed in
version 3.8: The default format for new archives was changed to
PAX_FORMAT from GNU_FORMAT.").

[So could it be possible that python3 is actually generating GNU_FORMAT
tar archives, but claiming that they are PAX_FORMAT? I've had a quick
look at Python-3.8.12/Lib/tarfile.py and it doesn't seem to have any
obvious error like this.]

The attached tarmtime.py script demonstrates the problem - it creates
various tar archives and extracts with `tar` and `pax` and shows the
`Jan  1  1970` mtimes.


Thanks for any advice here,

- Julian

-- 
http://op59.net
#!/usr/bin/env python3

import io
import os
import sys
import tarfile
import time

def system( command):
    print( 'running: %s' % command)
    sys.stdout.flush()
    return os.system( command)

with tarfile.open('tarmtime1.tgz', 'w:gz') as t:
    t.add( 'tarmtime.py', 'tarmtime1/tarmtime.py')
system( 'tar -xzf tarmtime1.tgz')
system( 'ls -l tarmtime1/*')

with tarfile.open('tarmtime2.tar', 'w') as t:
    t.add( 'tarmtime.py', 'tarmtime2/tarmtime.py')
system( 'tar -xf tarmtime2.tar')
system( 'ls -l tarmtime2/*')

if 1:
    with tarfile.open('tarmtime2.tar', 'r') as t:
        ti = t.getmember( 'tarmtime2/tarmtime.py')
        print( 'ti: name=%s size=%s mtime=%s' % (ti.name, ti.size, ti.mtime))


with tarfile.open('tarmtime3.tar', 'w') as t:
    data = b'123'
    
    ti = tarfile.TarInfo( 'tarmtime3/foo')
    ti.size = len( data)
    #ti.mtime = time.time()
    data2 = io.BytesIO(data)
    t.addfile(ti, data2)
    
    ti = tarfile.TarInfo( 'tarmtime3/bar')
    ti.size = len( data)
    ti.mtime = time.time()
    data2 = io.BytesIO(data)
    t.addfile(ti, data2)

system( 'tar -xf tarmtime3.tar')
system( 'ls -l tarmtime3/*')

system( 'pax -r -f tarmtime3.tar')
system( 'ls -l tarmtime3/*')
system( 'rm -r tarmtime3')

system( 'gtar -xf tarmtime3.tar')
system( 'ls -l tarmtime3/*')

if 1:
    with tarfile.open('tarmtime3.tar', 'r') as t:
        ti = t.getmember( 'tarmtime3/foo')
        print( 'ti: name=%s size=%s mtime=%s' % (ti.name, ti.size, ti.mtime))
        ti = t.getmember( 'tarmtime3/bar')
        print( 'ti: name=%s size=%s mtime=%s' % (ti.name, ti.size, ti.mtime))

print( 'Cleanup with: rm -r tarmtime1* tarmtime2* tarmtime3*')

Reply via email to