Commit df7b4317 authored by bescoto's avatar bescoto

Final changes for 0.12.4 (Mostly unreadable dir fix)


git-svn-id: http://svn.savannah.nongnu.org/svn/rdiff-backup@433 2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109
parent a25d5741
New in v0.12.4 (??????????)
New in v0.12.4 (2003/09/13)
---------------------------
Specified socket type as SOCK_STREAM. (Error reported by Erik
......
......@@ -53,9 +53,6 @@ process_gid = os.getgid()
# If true, when copying attributes, also change target's uid/gid
change_ownership = None
# If true, when copying attributes, also change target's permission.
change_permissions = 1
# If true, change the permissions of unwriteable mirror files
# (such as directories) so that they can be written, and then
# change them back. This defaults to 1 just in case the process
......
......@@ -291,8 +291,7 @@ def backup_init_dirs(rpin, rpout):
if rpout.lstat():
if rpout.isdir() and not rpout.listdir(): # rpout is empty dir
if Globals.change_permissions:
rpout.chmod(0700) # just make sure permissions aren't too lax
rpout.chmod(0700) # just make sure permissions aren't too lax
elif not datadir.lstat() and not force: Log.FatalError(
"""Destination directory
......
......@@ -228,7 +228,7 @@ static.MakeClass(DestinationStruct)
class CacheCollatedPostProcess:
"""Cache a collated iter of (source_rorp, dest_rorp) pairs
This is necessary for two reasons:
This is necessary for three reasons:
1. The patch function may need the original source_rorp or
dest_rp information, which is not present in the diff it
......@@ -241,6 +241,11 @@ class CacheCollatedPostProcess:
any metadata until we know the file has been procesed
correctly.
3. We may lack permissions on certain destination directories.
The permissions of these directories need to be relaxed before
we enter them to computer signatures, and then reset after we
are done patching everything inside them.
The class caches older source_rorps and dest_rps so the patch
function can retrieve them if necessary. The patch function can
also update the processed correctly flag. When an item falls out
......@@ -273,6 +278,11 @@ class CacheCollatedPostProcess:
self.cache_dict = {}
self.cache_indicies = []
# Contains a list of pairs (destination_rps, permissions) to
# be used to reset the permissions of certain directories
# after we're finished with them
self.dir_perms_list = []
def __iter__(self): return self
def next(self):
......@@ -296,10 +306,21 @@ class CacheCollatedPostProcess:
"""
if source_rorp: Hardlink.add_rorp(source_rorp, source = 1)
if dest_rorp: Hardlink.add_rorp(dest_rorp, source = 0)
if (dest_rorp and dest_rorp.isdir() and Globals.process_uid != 0 and
dest_rorp.getperms() % 01000 < 0700):
dest_rp = self.dest_root_rp.new_index(dest_rorp.index)
dest_rp.chmod(0700 | dest_rorp.getperms())
if (dest_rorp and dest_rorp.isdir() and Globals.process_uid != 0
and dest_rorp.getperms() % 01000 < 0700):
self.unreadable_dir_init(source_rorp, dest_rorp)
def unreadable_dir_init(self, source_rorp, dest_rorp):
"""Initialize an unreadable dir.
Make it readable, and if necessary, store the old permissions
in self.dir_perms_list so the old perms can be restored.
"""
dest_rp = self.dest_root_rp.new_index(dest_rorp.index)
dest_rp.chmod(0700 | dest_rorp.getperms())
if source_rorp and source_rorp.isdir():
self.dir_perms_list.append((dest_rp, source_rorp.getperms()))
def shorten_cache(self):
"""Remove one element from cache, possibly adding it to metadata"""
......@@ -314,6 +335,7 @@ class CacheCollatedPostProcess:
del self.cache_dict[first_index]
self.post_process(old_source_rorp, old_dest_rorp,
changed_flag, success_flag, inc)
if self.dir_perms_list: self.reset_dir_perms(first_index)
def post_process(self, source_rorp, dest_rorp, changed, success, inc):
"""Post process source_rorp and dest_rorp.
......@@ -338,12 +360,14 @@ class CacheCollatedPostProcess:
if Globals.file_statistics:
statistics.FileStats.update(source_rorp, dest_rorp, changed, inc)
# Update permissions of unreadable directory
if (source_rorp and source_rorp.isdir() and Globals.process_uid != 0
and success and source_rorp.getperms() % 01000 < 0700):
dest_rp = self.dest_root_rp.new_index(source_rorp.index)
assert dest_rp.isdir(), dest_rp
dest_rp.chmod(source_rorp.getperms())
def reset_dir_perms(self, current_index):
"""Reset the permissions of directories when we have left them"""
dir_rp, perms = self.dir_perms_list[-1]
dir_index = dir_rp.index
if (current_index > dir_index and
current_index[:len(dir_index)] != dir_index):
dir_rp.chmod(perms) # out of directory, reset perms now
del self.dir_perms_list[-1]
def in_cache(self, index):
"""Return true if given index is cached"""
......@@ -383,6 +407,9 @@ class CacheCollatedPostProcess:
def close(self):
"""Process the remaining elements in the cache"""
while self.cache_indicies: self.shorten_cache()
while self.dir_perms_list:
dir_rp, perms = self.dir_perms_list.pop()
dir_rp.chmod(perms)
metadata.CloseMetadata()
if Globals.print_statistics: statistics.print_active_stats()
if Globals.file_statistics: statistics.FileStats.close()
......@@ -490,6 +517,7 @@ class PatchITRB(rorpiter.ITRBranch):
"""Set self.dir_replacement, which holds data until done with dir
This is used when base_rp is a dir, and diff_rorp is not.
Returns 1 for success or 0 for failure
"""
assert diff_rorp.get_attached_filetype() == 'snapshot'
......@@ -499,10 +527,8 @@ class PatchITRB(rorpiter.ITRBranch):
# Was an error, so now restore original directory
rpath.copy_with_attribs(self.CCPP.get_mirror_rorp(diff_rorp.index),
self.dir_replacement)
success = 0
else: success = 1
if base_rp.isdir() and Globals.change_permissions: base_rp.chmod(0700)
return success
return 0
else: return 1
def prepare_dir(self, diff_rorp, base_rp):
"""Prepare base_rp to turn into a directory"""
......@@ -514,7 +540,6 @@ class PatchITRB(rorpiter.ITRBranch):
else: # maybe no change, so query CCPP before tagging success
if self.CCPP.in_cache(diff_rorp.index):
self.CCPP.flag_success(diff_rorp.index)
if Globals.change_permissions: base_rp.chmod(0700)
def end_process(self):
"""Finish processing directory"""
......
......@@ -250,8 +250,7 @@ class RegressITRB(rorpiter.ITRBranch):
if not rf.mirror_rp.isdir():
if rf.mirror_rp.lstat(): rf.mirror_rp.delete()
rf.mirror_rp.mkdir()
if Globals.change_permissions and not rf.mirror_rp.hasfullperms():
rf.mirror_rp.chmod(0700)
if not rf.mirror_rp.hasfullperms(): rf.mirror_rp.chmod(0700)
self.rf = rf
def end_process(self):
......
......@@ -576,7 +576,7 @@ class PatchITRB(rorpiter.ITRBranch):
assert diff_rorp.get_attached_filetype() == 'snapshot'
self.dir_replacement = TempFile.new(base_rp)
rpath.copy_with_attribs(diff_rorp, self.dir_replacement)
if base_rp.isdir() and Globals.change_permissions: base_rp.chmod(0700)
if base_rp.isdir(): base_rp.chmod(0700)
def prepare_dir(self, diff_rorp, base_rp):
"""Prepare base_rp to turn into a directory"""
......@@ -584,7 +584,7 @@ class PatchITRB(rorpiter.ITRBranch):
if not base_rp.isdir():
if base_rp.lstat(): base_rp.delete()
base_rp.mkdir()
if Globals.change_permissions: base_rp.chmod(0700)
base_rp.chmod(0700)
def end_process(self):
"""Finish processing directory"""
......
......@@ -154,7 +154,7 @@ def copy_attribs(rpin, rpout):
check_for_files(rpin, rpout)
if rpin.issym(): return # symlinks have no valid attributes
if Globals.change_ownership: apply(rpout.chown, rpin.getuidgid())
if Globals.change_permissions: rpout.chmod(rpin.getperms())
rpout.chmod(rpin.getperms())
if not rpin.isdev(): rpout.setmtime(rpin.getmtime())
def cmp_attribs(rp1, rp2):
......@@ -261,7 +261,6 @@ class RORPath:
for key in self.data.keys(): # compare dicts key by key
if (key == 'uid' or key == 'gid') and self.issym():
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 == 'devloc' or key == 'nlink': pass
elif key == 'size' and not self.isreg(): pass
......@@ -294,7 +293,6 @@ class RORPath:
elif key == 'atime' and not Globals.preserve_atime: 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
elif key == 'inode': pass
elif (not other.data.has_key(key) or
self.data[key] != other.data[key]): return 0
......@@ -312,7 +310,6 @@ class RORPath:
(self.issym() or not compare_ownership)):
# Don't compare gid/uid for symlinks, or if told not to
pass
elif key == 'perms' and not Globals.change_permissions: pass
elif key == 'atime' and not Globals.preserve_atime: pass
elif key == 'devloc' or key == 'nlink': pass
elif key == 'size' and not self.isreg(): pass
......
......@@ -416,6 +416,7 @@ class FinalCorrupt(PathSetter):
def make_dir(self):
self.delete_tmpdirs()
rp1 = rpath.RPath(Globals.local_connection, 'testfiles/final_deleted1')
print rp1
if rp1.lstat(): Myrm(rp1.path)
rp1.mkdir()
rp1_1 = rp1.append('regfile')
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment