2 from bup.helpers import *
5 O_LARGEFILE = os.O_LARGEFILE
9 O_NOFOLLOW = os.O_NOFOLLOW
10 except AttributeError:
14 # the use of fchdir() and lstat() is for two reasons:
15 # - help out the kernel by not making it repeatedly look up the absolute path
16 # - avoid race conditions caused by doing listdir() on a changing symlink
18 def __init__(self, path):
20 self.fd = os.open(path, os.O_RDONLY|O_LARGEFILE|O_NOFOLLOW|os.O_NDELAY)
32 return os.fstat(self.fd)
35 _IFMT = stat.S_IFMT(0xffffffff) # avoid function call in inner loop
38 for n in os.listdir('.'):
42 add_error(Exception('%s: %s' % (realpath(n), str(e))))
44 if (st.st_mode & _IFMT) == stat.S_IFDIR:
51 def _recursive_dirlist(prepend, xdev, bup_dir=None, excluded_paths=None):
52 for (name,pst) in _dirlist():
53 if name.endswith('/'):
54 if xdev != None and pst.st_dev != xdev:
55 log('Skipping %r: different filesystem.\n' % (prepend+name))
58 if os.path.normpath(prepend+name) == bup_dir:
59 log('Skipping BUP_DIR.\n')
62 if os.path.normpath(prepend+name) in excluded_paths:
63 log('Skipping %r: excluded.\n' % (prepend+name))
68 add_error('%s: %s' % (prepend, e))
70 for i in _recursive_dirlist(prepend=prepend+name, xdev=xdev,
72 excluded_paths=excluded_paths):
75 yield (prepend + name, pst)
78 def recursive_dirlist(paths, xdev, bup_dir=None, excluded_paths=None):
79 startdir = OsFile('.')
81 assert(type(paths) != type(''))
85 if stat.S_ISLNK(pst.st_mode):
89 add_error('recursive_dirlist: %s' % e)
101 if stat.S_ISDIR(pst.st_mode):
103 prepend = os.path.join(path, '')
104 for i in _recursive_dirlist(prepend=prepend, xdev=xdev,
106 excluded_paths=excluded_paths):
119 def parse_excludes(flags):
123 (option, parameter) = flag
124 if option == '--exclude':
125 excluded_paths.append(realpath(parameter))
127 if option == '--exclude-from':
130 f = open(realpath(parameter))
131 for exclude_path in f.readlines():
132 excluded_paths.append(realpath(exclude_path.strip()))
134 log("warning: couldn't read %s" % parameter)
138 return excluded_paths