"Fossies" - the Fresh Open Source Software Archive

Member "bup-0.30/lib/bup/drecurse.py" (28 Sep 2019, 4476 Bytes) of package /linux/privat/bup-0.30.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "drecurse.py" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 0.29.3_vs_0.30.

    1 
    2 from __future__ import absolute_import
    3 import stat, os
    4 
    5 from bup.helpers import add_error, should_rx_exclude_path, debug1, resolve_parent
    6 import bup.xstat as xstat
    7 
    8 
    9 try:
   10     O_LARGEFILE = os.O_LARGEFILE
   11 except AttributeError:
   12     O_LARGEFILE = 0
   13 try:
   14     O_NOFOLLOW = os.O_NOFOLLOW
   15 except AttributeError:
   16     O_NOFOLLOW = 0
   17 
   18 
   19 # the use of fchdir() and lstat() is for two reasons:
   20 #  - help out the kernel by not making it repeatedly look up the absolute path
   21 #  - avoid race conditions caused by doing listdir() on a changing symlink
   22 class OsFile:
   23     def __init__(self, path):
   24         self.fd = None
   25         self.fd = os.open(path, os.O_RDONLY|O_LARGEFILE|O_NOFOLLOW|os.O_NDELAY)
   26         
   27     def __del__(self):
   28         if self.fd:
   29             fd = self.fd
   30             self.fd = None
   31             os.close(fd)
   32 
   33     def fchdir(self):
   34         os.fchdir(self.fd)
   35 
   36     def stat(self):
   37         return xstat.fstat(self.fd)
   38 
   39 
   40 _IFMT = stat.S_IFMT(0xffffffff)  # avoid function call in inner loop
   41 def _dirlist():
   42     l = []
   43     for n in os.listdir('.'):
   44         try:
   45             st = xstat.lstat(n)
   46         except OSError as e:
   47             add_error(Exception('%s: %s' % (resolve_parent(n), str(e))))
   48             continue
   49         if (st.st_mode & _IFMT) == stat.S_IFDIR:
   50             n += '/'
   51         l.append((n,st))
   52     l.sort(reverse=True)
   53     return l
   54 
   55 
   56 def _recursive_dirlist(prepend, xdev, bup_dir=None,
   57                        excluded_paths=None,
   58                        exclude_rxs=None,
   59                        xdev_exceptions=frozenset()):
   60     for (name,pst) in _dirlist():
   61         path = prepend + name
   62         if excluded_paths:
   63             if os.path.normpath(path) in excluded_paths:
   64                 debug1('Skipping %r: excluded.\n' % path)
   65                 continue
   66         if exclude_rxs and should_rx_exclude_path(path, exclude_rxs):
   67             continue
   68         if name.endswith('/'):
   69             if bup_dir != None:
   70                 if os.path.normpath(path) == bup_dir:
   71                     debug1('Skipping BUP_DIR.\n')
   72                     continue
   73             if xdev != None and pst.st_dev != xdev \
   74                and path not in xdev_exceptions:
   75                 debug1('Skipping contents of %r: different filesystem.\n' % path)
   76             else:
   77                 try:
   78                     OsFile(name).fchdir()
   79                 except OSError as e:
   80                     add_error('%s: %s' % (prepend, e))
   81                 else:
   82                     for i in _recursive_dirlist(prepend=prepend+name, xdev=xdev,
   83                                                 bup_dir=bup_dir,
   84                                                 excluded_paths=excluded_paths,
   85                                                 exclude_rxs=exclude_rxs,
   86                                                 xdev_exceptions=xdev_exceptions):
   87                         yield i
   88                     os.chdir('..')
   89         yield (path, pst)
   90 
   91 
   92 def recursive_dirlist(paths, xdev, bup_dir=None,
   93                       excluded_paths=None,
   94                       exclude_rxs=None,
   95                       xdev_exceptions=frozenset()):
   96     startdir = OsFile('.')
   97     try:
   98         assert(type(paths) != type(''))
   99         for path in paths:
  100             try:
  101                 pst = xstat.lstat(path)
  102                 if stat.S_ISLNK(pst.st_mode):
  103                     yield (path, pst)
  104                     continue
  105             except OSError as e:
  106                 add_error('recursive_dirlist: %s' % e)
  107                 continue
  108             try:
  109                 pfile = OsFile(path)
  110             except OSError as e:
  111                 add_error(e)
  112                 continue
  113             pst = pfile.stat()
  114             if xdev:
  115                 xdev = pst.st_dev
  116             else:
  117                 xdev = None
  118             if stat.S_ISDIR(pst.st_mode):
  119                 pfile.fchdir()
  120                 prepend = os.path.join(path, '')
  121                 for i in _recursive_dirlist(prepend=prepend, xdev=xdev,
  122                                             bup_dir=bup_dir,
  123                                             excluded_paths=excluded_paths,
  124                                             exclude_rxs=exclude_rxs,
  125                                             xdev_exceptions=xdev_exceptions):
  126                     yield i
  127                 startdir.fchdir()
  128             else:
  129                 prepend = path
  130             yield (prepend,pst)
  131     except:
  132         try:
  133             startdir.fchdir()
  134         except:
  135             pass
  136         raise