2 from bup.helpers import *
3 import bup.xstat as xstat
6 O_LARGEFILE = os.O_LARGEFILE
10 O_NOFOLLOW = os.O_NOFOLLOW
11 except AttributeError:
15 # the use of fchdir() and lstat() is for two reasons:
16 # - help out the kernel by not making it repeatedly look up the absolute path
17 # - avoid race conditions caused by doing listdir() on a changing symlink
19 def __init__(self, path):
21 self.fd = os.open(path, os.O_RDONLY|O_LARGEFILE|O_NOFOLLOW|os.O_NDELAY)
33 return xstat.fstat(self.fd)
36 _IFMT = stat.S_IFMT(0xffffffff) # avoid function call in inner loop
39 for n in os.listdir('.'):
43 add_error(Exception('%s: %s' % (realpath(n), str(e))))
45 if (st.st_mode & _IFMT) == stat.S_IFDIR:
52 def _recursive_dirlist(prepend, xdev, bup_dir=None, excluded_paths=None):
53 for (name,pst) in _dirlist():
54 if name.endswith('/'):
55 if xdev != None and pst.st_dev != xdev:
56 debug1('Skipping %r: different filesystem.\n' % (prepend+name))
59 if os.path.normpath(prepend+name) == bup_dir:
60 debug1('Skipping BUP_DIR.\n')
63 if os.path.normpath(prepend+name) in excluded_paths:
64 debug1('Skipping %r: excluded.\n' % (prepend+name))
69 add_error('%s: %s' % (prepend, e))
71 for i in _recursive_dirlist(prepend=prepend+name, xdev=xdev,
73 excluded_paths=excluded_paths):
76 yield (prepend + name, pst)
79 def recursive_dirlist(paths, xdev, bup_dir=None, excluded_paths=None):
80 startdir = OsFile('.')
82 assert(type(paths) != type(''))
85 pst = xstat.lstat(path)
86 if stat.S_ISLNK(pst.st_mode):
90 add_error('recursive_dirlist: %s' % e)
102 if stat.S_ISDIR(pst.st_mode):
104 prepend = os.path.join(path, '')
105 for i in _recursive_dirlist(prepend=prepend, xdev=xdev,
107 excluded_paths=excluded_paths):
120 def parse_excludes(flags):
124 (option, parameter) = flag
125 if option == '--exclude':
126 excluded_paths.append(realpath(parameter))
128 if option == '--exclude-from':
131 f = open(realpath(parameter))
132 for exclude_path in f.readlines():
133 excluded_paths.append(realpath(exclude_path.strip()))
135 log("warning: couldn't read %s\n" % parameter)
139 return excluded_paths