Skip to content

Commit

Permalink
Merge pull request #63 from zweger/develop-birthtime
Browse files Browse the repository at this point in the history
Add support for birthtime field
  • Loading branch information
Changaco authored Jun 10, 2018
2 parents e15d221 + e49ff04 commit c4d812a
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 9 deletions.
10 changes: 10 additions & 0 deletions libarchive/entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,16 @@ def set_ctime(self, timestamp_sec, timestamp_nsec):
return ffi.entry_set_ctime(self._entry_p,
timestamp_sec, timestamp_nsec)

@property
def birthtime(self):
sec_val = ffi.entry_birthtime(self._entry_p)
nsec_val = ffi.entry_birthtime_nsec(self._entry_p)
return format_time(sec_val, nsec_val)

def set_birthtime(self, timestamp_sec, timestamp_nsec):
return ffi.entry_set_birthtime(self._entry_p,
timestamp_sec, timestamp_nsec)

def _getpathname(self):
return (ffi.entry_pathname_w(self._entry_p) or
ffi.entry_pathname(self._entry_p))
Expand Down
3 changes: 3 additions & 0 deletions libarchive/ffi.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,11 @@ def ffi(name, argtypes, restype, errcheck=None):

ffi('entry_filetype', [c_archive_entry_p], c_int)
ffi('entry_atime', [c_archive_entry_p], c_int)
ffi('entry_birthtime', [c_archive_entry_p], c_int)
ffi('entry_mtime', [c_archive_entry_p], c_int)
ffi('entry_ctime', [c_archive_entry_p], c_int)
ffi('entry_atime_nsec', [c_archive_entry_p], c_long)
ffi('entry_birthtime_nsec', [c_archive_entry_p], c_long)
ffi('entry_mtime_nsec', [c_archive_entry_p], c_long)
ffi('entry_ctime_nsec', [c_archive_entry_p], c_long)
ffi('entry_pathname', [c_archive_entry_p], c_char_p)
Expand All @@ -141,6 +143,7 @@ def ffi(name, argtypes, restype, errcheck=None):
ffi('entry_set_atime', [c_archive_entry_p, c_int, c_long], None)
ffi('entry_set_mtime', [c_archive_entry_p, c_int, c_long], None)
ffi('entry_set_ctime', [c_archive_entry_p, c_int, c_long], None)
ffi('entry_set_birthtime', [c_archive_entry_p, c_int, c_long], None)

ffi('entry_update_pathname_utf8', [c_archive_entry_p, c_char_p], None)

Expand Down
29 changes: 20 additions & 9 deletions tests/test_atime_mtime_ctime.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
from copy import copy
from os import stat

from libarchive import (file_reader, file_writer, memory_reader,
memory_writer)
from libarchive import (file_reader, file_writer, memory_reader, memory_writer)

import pytest

Expand Down Expand Up @@ -66,53 +65,65 @@ def test_file_atime_ctime(archfmt, timefmt, tmpdir):

@pytest.mark.parametrize('archfmt,timefmt', [('zip', int), ('pax', float)])
def test_memory_time_setters(archfmt, timefmt):
# Create an archive of our libarchive/ directory
has_birthtime = archfmt != 'zip'

atimestamp = (1482144741, 495628118)
mtimestamp = (1482155417, 659017086)
ctimestamp = (1482145211, 536858081)
# Create an archive of our libarchive/ directory
buf = bytes(bytearray(1000000))
with memory_writer(buf, archfmt) as archive1:
archive1.add_files('libarchive/')

atimestamp = (1482144741, 495628118)
mtimestamp = (1482155417, 659017086)
ctimestamp = (1482145211, 536858081)
btimestamp = (1482144740, 495628118)
buf2 = bytes(bytearray(1000000))
with memory_reader(buf) as archive1:
with memory_writer(buf2, archfmt) as archive2:
for entry in archive1:
entry.set_atime(*atimestamp)
entry.set_mtime(*mtimestamp)
entry.set_ctime(*ctimestamp)
if has_birthtime:
entry.set_birthtime(*btimestamp)
archive2.add_entries([entry])

with memory_reader(buf2) as archive2:
for entry in archive2:
assert entry.atime == time_check(atimestamp, timefmt)
assert entry.mtime == time_check(mtimestamp, timefmt)
assert entry.ctime == time_check(ctimestamp, timefmt)
if has_birthtime:
assert entry.birthtime == time_check(btimestamp, timefmt)


@pytest.mark.parametrize('archfmt,timefmt', [('zip', int), ('pax', float)])
def test_file_time_setters(archfmt, timefmt, tmpdir):
has_birthtime = archfmt != 'zip'

# Create an archive of our libarchive/ directory
archive_path = tmpdir.join('/test.{0}'.format(archfmt)).strpath
archive2_path = tmpdir.join('/test2.{0}'.format(archfmt)).strpath
with file_writer(archive_path, archfmt) as archive1:
archive1.add_files('libarchive/')

atimestamp = (1482144741, 495628118)
mtimestamp = (1482155417, 659017086)
ctimestamp = (1482145211, 536858081)
with file_writer(archive_path, archfmt) as archive1:
archive1.add_files('libarchive/')

btimestamp = (1482144740, 495628118)
with file_reader(archive_path) as archive1:
with file_writer(archive2_path, archfmt) as archive2:
for entry in archive1:
entry.set_atime(*atimestamp)
entry.set_mtime(*mtimestamp)
entry.set_ctime(*ctimestamp)
if has_birthtime:
entry.set_birthtime(*btimestamp)
archive2.add_entries([entry])

with file_reader(archive2_path) as archive2:
for entry in archive2:
assert entry.atime == time_check(atimestamp, timefmt)
assert entry.mtime == time_check(mtimestamp, timefmt)
assert entry.ctime == time_check(ctimestamp, timefmt)
if has_birthtime:
assert entry.birthtime == time_check(btimestamp, timefmt)

0 comments on commit c4d812a

Please sign in to comment.