summaryrefslogtreecommitdiff
path: root/rdiff-backup/rdiff_backup/destructive_stepping.py
diff options
context:
space:
mode:
Diffstat (limited to 'rdiff-backup/rdiff_backup/destructive_stepping.py')
-rw-r--r--rdiff-backup/rdiff_backup/destructive_stepping.py212
1 files changed, 0 insertions, 212 deletions
diff --git a/rdiff-backup/rdiff_backup/destructive_stepping.py b/rdiff-backup/rdiff_backup/destructive_stepping.py
deleted file mode 100644
index 6dc77e7..0000000
--- a/rdiff-backup/rdiff_backup/destructive_stepping.py
+++ /dev/null
@@ -1,212 +0,0 @@
-
-# Copyright 2002 Ben Escoto
-#
-# This file is part of rdiff-backup.
-#
-# rdiff-backup is free software; you can redistribute it and/or modify
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version.
-#
-# rdiff-backup is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with rdiff-backup; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-# USA
-
-"""Deal with side effects from traversing trees"""
-
-from __future__ import generators
-import types
-import Globals, rpath, log
-
-
-class DSRPPermError(Exception):
- """Exception used when a DSRPath can't get sufficient permissions"""
- pass
-
-class DSRPath(rpath.RPath):
- """Destructive Stepping RPath
-
- Sometimes when we traverse the directory tree, even when we just
- want to read files, we have to change things, like the permissions
- of a file or directory in order to read it, or the file's access
- times. This class is like an RPath, but the permission and time
- modifications are delayed, so that they can be done at the very
- end when they won't be disturbed later.
-
- Here are the new class variables:
- delay_perms - true iff future perm changes should be delayed
- newperms - holds the perm values while they are delayed
- delay_atime - true iff some atime change are being delayed
- newatime - holds the new atime
- delay_mtime - true if some mtime change is being delayed
- newmtime - holds the new mtime
-
- """
- def __init__(self, source, conn_or_rp, base = 0, index = ()):
- """Initialize DSRP
-
- Source should be true iff the DSRPath is taken from the
- "source" partition and thus settings like
- Globals.change_source_perms should be paid attention to.
-
- If args is [rpath], return the dsrpath equivalent of rpath,
- otherwise use the same arguments as the RPath initializer.
-
- """
- if base == 0:
- assert isinstance(conn_or_rp, rpath.RPath)
- rpath.RPath.__init__(self, conn_or_rp.conn,
- conn_or_rp.base, conn_or_rp.index)
- self.path = conn_or_rp.path # conn_or_rp may be quoted
- else: rpath.RPath.__init__(self, conn_or_rp, base, index)
-
- if source != "bypass":
- # "bypass" val is used when unpackaging over connection
- assert source is None or source is 1
- self.source = source
- self.set_delays(source)
- self.set_init_perms(source)
-
- def set_delays(self, source):
- """Delay writing permissions and times where appropriate"""
- if not source or Globals.change_source_perms:
- self.delay_perms, self.newperms = 1, None
- else: self.delay_perms = None
-
- if Globals.preserve_atime:
- self.delay_atime = 1
- # Now get atime right away if possible
- if self.data.has_key('atime'): self.newatime = self.data['atime']
- else: self.newatime = None
- else: self.delay_atime = None
-
- if source:
- self.delay_mtime = None # we'll never change mtime of source file
- else:
- self.delay_mtime = 1
- # Save mtime now for a dir, because it might inadvertantly change
- if self.isdir(): self.newmtime = self.data['mtime']
- else: self.newmtime = None
-
- def set_init_perms(self, source):
- """If necessary, change permissions to ensure access"""
- if self.isreg() and not self.readable():
- if (source and Globals.change_source_perms or
- not source and Globals.change_mirror_perms):
- self.chmod_bypass(0400)
- elif self.isdir():
- if source and Globals.change_source_perms:
- if not self.readable() or not self.executable():
- self.chmod_bypass(0500)
- elif not source and Globals.change_mirror_perms:
- if not self.hasfullperms(): self.chmod_bypass(0700)
-
- def warn(self, err):
- log.Log("Received error '%s' when dealing with file %s, skipping..."
- % (err, self.path), 1)
- raise DSRPPermError(self.path)
-
- def __getstate__(self):
- """Return picklable state. See RPath __getstate__."""
- assert self.conn is Globals.local_connection # Can't pickle a conn
- return self.getstatedict()
-
- def getstatedict(self):
- """Return dictionary containing the attributes we can save"""
- pickle_dict = {}
- for attrib in ['index', 'data', 'delay_perms', 'newperms',
- 'delay_atime', 'newatime',
- 'delay_mtime', 'newmtime',
- 'path', 'base', 'source']:
- if self.__dict__.has_key(attrib):
- pickle_dict[attrib] = self.__dict__[attrib]
- return pickle_dict
-
- def __setstate__(self, pickle_dict):
- """Set state from object produced by getstate"""
- self.conn = Globals.local_connection
- for attrib in pickle_dict.keys():
- self.__dict__[attrib] = pickle_dict[attrib]
-
- def chmod(self, permissions):
- """Change permissions, delaying if self.perms_delayed is set"""
- if self.delay_perms: self.newperms = self.data['perms'] = permissions
- else: rpath.RPath.chmod(self, permissions)
-
- def getperms(self):
- """Return dsrp's intended permissions"""
- if self.delay_perms and self.newperms is not None:
- return self.newperms
- else: return self.data['perms']
-
- def chmod_bypass(self, permissions):
- """Change permissions without updating the data dictionary"""
- self.delay_perms = 1
- if self.newperms is None: self.newperms = self.getperms()
- log.Log("DSRP: Perm bypass %s to %o" % (self.path, permissions), 8)
- self.conn.os.chmod(self.path, permissions)
-
- def settime(self, accesstime, modtime):
- """Change times, delaying if self.times_delayed is set"""
- if self.delay_atime: self.newatime = self.data['atime'] = accesstime
- if self.delay_mtime: self.newmtime = self.data['mtime'] = modtime
-
- if not self.delay_atime or not self.delay_mtime:
- rpath.RPath.settime(self, accesstime, modtime)
-
- def setmtime(self, modtime):
- """Change mtime, delaying if self.times_delayed is set"""
- if self.delay_mtime: self.newmtime = self.data['mtime'] = modtime
- else: rpath.RPath.setmtime(self, modtime)
-
- def getmtime(self):
- """Return dsrp's intended modification time"""
- if self.delay_mtime and self.newmtime is not None:
- return self.newmtime
- else: return self.data['mtime']
-
- def getatime(self):
- """Return dsrp's intended access time"""
- if self.delay_atime and self.newatime is not None:
- return self.newatime
- else: return self.data['atime']
-
- def write_changes(self):
- """Write saved up permission/time changes"""
- if not self.lstat(): return # File has been deleted in meantime
-
- if self.delay_perms and self.newperms is not None:
- log.Log("Finalizing permissions of dsrp %s to %s" %
- (self.path, self.newperms), 8)
- rpath.RPath.chmod(self, self.newperms)
-
- do_atime = self.delay_atime and self.newatime is not None
- do_mtime = self.delay_mtime and self.newmtime is not None
- if do_atime and do_mtime:
- rpath.RPath.settime(self, self.newatime, self.newmtime)
- elif do_atime and not do_mtime:
- rpath.RPath.settime(self, self.newatime, self.getmtime())
- elif not do_atime and do_mtime:
- rpath.RPath.setmtime(self, self.newmtime)
-
- def newpath(self, newpath, index = ()):
- """Return similar DSRPath but with new path"""
- return self.__class__(self.source, self.conn, newpath, index)
-
- def append(self, ext):
- """Return similar DSRPath with new extension"""
- return self.__class__(self.source, self.conn, self.base,
- self.index + (ext,))
-
- def new_index(self, index):
- """Return similar DSRPath with new index"""
- return self.__class__(self.source, self.conn, self.base, index)
-
-
-