summaryrefslogtreecommitdiff
path: root/rdiff-backup/rdiff_backup/selection.py
diff options
context:
space:
mode:
Diffstat (limited to 'rdiff-backup/rdiff_backup/selection.py')
-rw-r--r--rdiff-backup/rdiff_backup/selection.py70
1 files changed, 43 insertions, 27 deletions
diff --git a/rdiff-backup/rdiff_backup/selection.py b/rdiff-backup/rdiff_backup/selection.py
index 45d4c8c..6c4cabe 100644
--- a/rdiff-backup/rdiff_backup/selection.py
+++ b/rdiff-backup/rdiff_backup/selection.py
@@ -26,8 +26,7 @@ documentation on what this code does can be found on the man page.
from __future__ import generators
import re
-from log import Log
-import FilenameMapping, robust, rpath, Globals
+import FilenameMapping, robust, rpath, Globals, log
class SelectError(Exception):
@@ -87,7 +86,7 @@ class Select:
self.rpath = rootrp
self.prefix = self.rpath.path
- def set_iter(self, iterate_parents = None, sel_func = None):
+ def set_iter(self, sel_func = None):
"""Initialize more variables, get ready to iterate
Selection function sel_func is called on each rpath and is
@@ -96,17 +95,24 @@ class Select:
"""
if not sel_func: sel_func = self.Select
self.rpath.setdata() # this may have changed since Select init
- self.iter = self.Iterate_fast(self.rpath, sel_func)
-
- # only iterate parents if we are not starting from beginning
+ self.iter = self.filter_readable(self.Iterate_fast(self.rpath,
+ sel_func))
self.next = self.iter.next
self.__iter__ = lambda: self
return self
+ def filter_readable(self, rp_iter):
+ """Yield rps in iter except the unreadable regular files"""
+ for rp in rp_iter:
+ if not rp.isreg() or rp.readable(): yield rp
+ else: log.ErrorLog.write_if_open("ListError", rp,
+ "Regular file lacks read permissions")
+
def Iterate_fast(self, rpath, sel_func):
"""Like Iterate, but don't recur, saving time"""
def error_handler(exc, filename):
- Log("Error initializing file %s/%s" % (rpath.path, filename), 2)
+ log.ErrorLog.write_if_open("ListError",
+ rpath.index + (filename,), exc)
return None
def diryield(rpath):
@@ -117,7 +123,7 @@ class Select:
and should be included iff something inside is included.
"""
- for filename in robust.listrp(rpath):
+ for filename in self.listdir(rpath):
new_rpath = robust.check_common_error(error_handler,
rpath.append, (filename,))
if new_rpath:
@@ -174,13 +180,23 @@ class Select:
for rp in iid: yield rp
else: assert 0, "Invalid selection result %s" % (str(s),)
+ def listdir(self, dir_rp):
+ """List directory rpath with error logging"""
+ def error_handler(exc):
+ log.ErrorLog.write_if_open("ListError", dir_rp, exc)
+ return []
+ dir_listing = robust.check_common_error(error_handler, dir_rp.listdir)
+ dir_listing.sort()
+ return dir_listing
+
def iterate_in_dir(self, rpath, rec_func, sel_func):
"""Iterate the rpaths in directory rpath."""
def error_handler(exc, filename):
- Log("Error initializing file %s/%s" % (rpath.path, filename), 2)
+ log.ErrorLog.write_if_open("ListError",
+ rpath.index + (filename,), exc)
return None
- for filename in robust.listrp(rpath):
+ for filename in self.listdir(rpath):
new_rp = robust.check_common_error(
error_handler, rpath.append, [filename])
if new_rp:
@@ -251,7 +267,7 @@ class Select:
def parse_catch_error(self, exc):
"""Deal with selection error exc"""
if isinstance(exc, FilePrefixError):
- Log.FatalError(
+ log.Log.FatalError(
"""Fatal Error: The file specification
' %s'
cannot match any files in the base directory
@@ -260,8 +276,8 @@ Useful file specifications begin with the base directory or some
pattern (such as '**') which matches the base directory.""" %
(exc, self.prefix))
elif isinstance(e, GlobbingError):
- Log.FatalError("Fatal Error while processing expression\n"
- "%s" % exc)
+ log.Log.FatalError("Fatal Error while processing expression\n"
+ "%s" % exc)
else: raise
def parse_rbdir_exclude(self):
@@ -273,7 +289,7 @@ pattern (such as '**') which matches the base directory.""" %
"""Exit with error if last selection function isn't an exclude"""
if (self.selection_functions and
not self.selection_functions[-1].exclude):
- Log.FatalError(
+ log.Log.FatalError(
"""Last selection expression:
%s
only specifies that files be included. Because the default is to
@@ -296,10 +312,10 @@ probably isn't what you meant.""" %
filelist_name is just a string used for logging.
"""
- Log("Reading filelist %s" % filelist_name, 4)
+ log.Log("Reading filelist %s" % filelist_name, 4)
tuple_list, something_excluded = \
self.filelist_read(filelist_fp, inc_default, filelist_name)
- Log("Sorting filelist %s" % filelist_name, 4)
+ log.Log("Sorting filelist %s" % filelist_name, 4)
tuple_list.sort()
i = [0] # We have to put index in list because of stupid scoping rules
@@ -324,11 +340,11 @@ probably isn't what you meant.""" %
"""Warn if prefix is incorrect"""
prefix_warnings[0] += 1
if prefix_warnings[0] < 6:
- Log("Warning: file specification '%s' in filelist %s\n"
- "doesn't start with correct prefix %s. Ignoring." %
- (exc, filelist_name, self.prefix), 2)
+ log.Log("Warning: file specification '%s' in filelist %s\n"
+ "doesn't start with correct prefix %s. Ignoring." %
+ (exc, filelist_name, self.prefix), 2)
if prefix_warnings[0] == 5:
- Log("Future prefix errors will not be logged.", 2)
+ log.Log("Future prefix errors will not be logged.", 2)
something_excluded, tuple_list = None, []
separator = Globals.null_separator and "\0" or "\n"
@@ -341,7 +357,7 @@ probably isn't what you meant.""" %
tuple_list.append(tuple)
if not tuple[1]: something_excluded = 1
if filelist_fp.close():
- Log("Error closing filelist %s" % filelist_name, 2)
+ log.Log("Error closing filelist %s" % filelist_name, 2)
return (tuple_list, something_excluded)
def filelist_parse_line(self, line, include):
@@ -399,7 +415,7 @@ probably isn't what you meant.""" %
See the man page on --[include/exclude]-globbing-filelist
"""
- Log("Reading globbing filelist %s" % list_name, 4)
+ log.Log("Reading globbing filelist %s" % list_name, 4)
separator = Globals.null_separator and "\0" or "\n"
for line in filelist_fp.read().split(separator):
if not line: continue # skip blanks
@@ -423,7 +439,7 @@ probably isn't what you meant.""" %
assert include == 0 or include == 1
try: regexp = re.compile(regexp_string)
except:
- Log("Error compiling regular expression %s" % regexp_string, 1)
+ log.Log("Error compiling regular expression %s" % regexp_string, 1)
raise
def sel_func(rp):
@@ -437,8 +453,8 @@ probably isn't what you meant.""" %
def devfiles_get_sf(self, include):
"""Return a selection function matching all dev files"""
if self.selection_functions:
- Log("Warning: exclude-device-files is not the first "
- "selector.\nThis may not be what you intended", 3)
+ log.Log("Warning: exclude-device-files is not the first "
+ "selector.\nThis may not be what you intended", 3)
def sel_func(rp):
if rp.isdev(): return include
else: return None
@@ -449,8 +465,8 @@ probably isn't what you meant.""" %
def special_get_sf(self, include):
"""Return sel function matching sockets, symlinks, sockets, devs"""
if self.selection_functions:
- Log("Warning: exclude-special-files is not the first "
- "selector.\nThis may not be what you intended", 3)
+ log.Log("Warning: exclude-special-files is not the first "
+ "selector.\nThis may not be what you intended", 3)
def sel_func(rp):
if rp.issym() or rp.issock() or rp.isfifo() or rp.isdev():
return include