summaryrefslogtreecommitdiff
path: root/rdiff-backup
diff options
context:
space:
mode:
Diffstat (limited to 'rdiff-backup')
-rw-r--r--rdiff-backup/rdiff_backup/cmodule.c10
-rw-r--r--rdiff-backup/rdiff_backup/rpath.py8
-rw-r--r--rdiff-backup/testing/rpathtest.py38
3 files changed, 50 insertions, 6 deletions
diff --git a/rdiff-backup/rdiff_backup/cmodule.c b/rdiff-backup/rdiff_backup/cmodule.c
index 59b93e2..0f01118 100644
--- a/rdiff-backup/rdiff_backup/cmodule.c
+++ b/rdiff-backup/rdiff_backup/cmodule.c
@@ -45,7 +45,7 @@ static PyObject *c_make_file_dict(self, args)
PyObject *self;
PyObject *args;
{
- PyObject *size, *inode, *mtime, *atime, *devloc, *return_val;
+ PyObject *size, *inode, *mtime, *atime, *ctime, *devloc, *return_val;
char *filename, filetype[5];
STRUCT_STAT sbuf;
long int mode, perms;
@@ -82,9 +82,11 @@ static PyObject *c_make_file_dict(self, args)
#if SIZEOF_TIME_T > SIZEOF_LONG
mtime = PyLong_FromLongLong((LONG_LONG)sbuf.st_mtime);
atime = PyLong_FromLongLong((LONG_LONG)sbuf.st_atime);
+ ctime = PyLong_FromLongLong((LONG_LONG)sbuf.st_ctime);
#else
mtime = PyInt_FromLong((long)sbuf.st_mtime);
atime = PyInt_FromLong((long)sbuf.st_atime);
+ ctime = PyInt_FromLong((long)sbuf.st_ctime);
#endif
/* Build return dictionary from stat struct */
@@ -94,7 +96,7 @@ static PyObject *c_make_file_dict(self, args)
else if S_ISDIR(mode) strcpy(filetype, "dir");
else if S_ISSOCK(mode) strcpy(filetype, "sock");
else strcpy(filetype, "fifo");
- return_val = Py_BuildValue("{s:s,s:O,s:l,s:l,s:l,s:O,s:O,s:l,s:O,s:O}",
+ return_val = Py_BuildValue("{s:s,s:O,s:l,s:l,s:l,s:O,s:O,s:l,s:O,s:O,s:O}",
"type", filetype,
"size", size,
"perms", perms,
@@ -104,7 +106,8 @@ static PyObject *c_make_file_dict(self, args)
"devloc", devloc,
"nlink", (long)sbuf.st_nlink,
"mtime", mtime,
- "atime", atime);
+ "atime", atime,
+ "ctime", ctime);
} else if S_ISLNK(mode) {
/* Symbolic links */
char linkname[1024];
@@ -160,6 +163,7 @@ static PyObject *c_make_file_dict(self, args)
Py_DECREF(devloc);
Py_DECREF(mtime);
Py_DECREF(atime);
+ Py_DECREF(ctime);
return return_val;
}
diff --git a/rdiff-backup/rdiff_backup/rpath.py b/rdiff-backup/rdiff_backup/rpath.py
index 51f49c6..e54d46b 100644
--- a/rdiff-backup/rdiff_backup/rpath.py
+++ b/rdiff-backup/rdiff_backup/rpath.py
@@ -169,6 +169,7 @@ def cmp_attribs(rp1, rp2):
if Globals.change_ownership and rp1.getuidgid() != rp2.getuidgid():
result = None
elif rp1.getperms() != rp2.getperms(): result = None
+ elif rp1.getctime() != rp2.getctime(): result = None
elif rp1.issym() and rp2.issym(): # Don't check times for some types
result = 1
elif rp1.isblkdev() and rp2.isblkdev(): result = 1
@@ -264,6 +265,7 @@ class RORPath:
pass # Don't compare gid/uid for symlinks
elif key == 'perms' and not Globals.change_permissions: pass
elif key == 'atime' and not Globals.preserve_atime: pass
+ elif key == 'ctime': pass
elif key == 'devloc' or key == 'nlink': pass
elif key == 'size' and not self.isreg(): pass
elif (key == 'inode' and
@@ -293,6 +295,7 @@ class RORPath:
other.isreg() and other.getsize() == 0):
pass # Special files may be replaced with empty regular files
elif key == 'atime' and not Globals.preserve_atime: pass
+ elif key == 'ctime': pass
elif key == 'devloc' or key == 'nlink': pass
elif key == 'size' and not self.isreg(): pass
elif key == 'perms' and not Globals.change_permissions: pass
@@ -316,6 +319,7 @@ class RORPath:
pass
elif key == 'perms' and not Globals.change_permissions: pass
elif key == 'atime' and not Globals.preserve_atime: pass
+ elif key == 'ctime': pass
elif key == 'devloc' or key == 'nlink': pass
elif key == 'size' and not self.isreg(): pass
elif key == 'inode' and (not self.isreg() or not compare_inodes):
@@ -430,6 +434,10 @@ class RORPath:
def getmtime(self):
"""Return modification time in seconds"""
return self.data['mtime']
+
+ def getctime(self):
+ """Return change time in seconds"""
+ return self.data['ctime']
def getinode(self):
"""Return inode number of file"""
diff --git a/rdiff-backup/testing/rpathtest.py b/rdiff-backup/testing/rpathtest.py
index d4f8487..26c3ea5 100644
--- a/rdiff-backup/testing/rpathtest.py
+++ b/rdiff-backup/testing/rpathtest.py
@@ -1,4 +1,4 @@
-import os, cPickle, sys, unittest
+import os, cPickle, sys, unittest, time
from commontest import *
from rdiff_backup.rpath import *
from rdiff_backup import rpath
@@ -91,6 +91,37 @@ class CheckPerms(RPathTest):
RPath(self.lc, self.prefix, ("aoeunto",)).getperms)
+class CheckTimes(RPathTest):
+ """Check to see if times are reported and set accurately"""
+ def testSet(self):
+ """Check to see if times set properly"""
+ rp = RPath(self.lc, self.prefix, ("timetest.foo",))
+ rp.touch()
+ rp.settime(10000, 20000)
+ rp.setdata()
+ assert rp.getatime() == 10000
+ assert rp.getmtime() == 20000
+ rp.delete()
+
+ def testCtime(self):
+ """Check to see if ctime read, compared"""
+ rp = RPath(self.lc, self.prefix, ("ctimetest.1",))
+ rp2 = RPath(self.lc, self.prefix, ("ctimetest.2",))
+ rp.touch()
+ rp.chmod(0700)
+ copy_with_attribs(rp, rp2)
+ assert cmp_attribs(rp, rp2)
+
+ time.sleep(1)
+ rp2.chmod(0755)
+ rp2.chmod(0700)
+ rp2.setdata()
+ assert rp2.getctime() > rp.getctime()
+ assert not cmp_attribs(rp, rp2)
+ rp.delete()
+ rp2.delete()
+
+
class CheckDir(RPathTest):
"""Check directory related functions"""
def testCreation(self):
@@ -386,9 +417,10 @@ class FileAttributes(FileCopying):
if t.lstat(): t.delete()
for rp in [self.noperms, self.nowrite, self.rf, self.exec1,
self.exec2, self.hl1, self.dir]:
- t.touch()
+ copy(rp, t)
rpath.copy_attribs(rp, t)
- assert rpath.cmp_attribs(t, rp), \
+ #assert rpath.cmp_attribs(t, rp), \
+ assert t.equal_loose(rp), \
"Attributes for file %s not copied successfully" % rp.path
t.delete()