diff options
Diffstat (limited to '')
| -rwxr-xr-x | src/bfind.py | 69 | 
1 files changed, 69 insertions, 0 deletions
| diff --git a/src/bfind.py b/src/bfind.py new file mode 100755 index 0000000..6edd67c --- /dev/null +++ b/src/bfind.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 +''' +bfind – Minimalitic `find` using breadth first crawling + +Copyright © 2013  Mattias Andrée (maandree@member.fsf.org) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program 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 this program.  If not, see <http://www.gnu.org/licenses/>. +''' + +import sys +import os + +xdev = False +hardlinks = False +symlinks = False +path = '' + +for arg in sys.argv[1:]: +    if dashed or arg[:1] != '-':  path   = arg +    elif arg == '':               dashed = True +    else: +        if arg == '--xdev'      or (arg[:2] != '--' and 'x' in arg):  xdev      = True +        if arg == '--hardlinks' or (arg[:2] != '--' and 'h' in arg):  hardlinks = True +        if arg == '--symlinks'  or (arg[:2] != '--' and 's' in arg):  symlinks  = True + +visited_name = set() +visited_id = set() +queue = None +start_dev = os.stat(path if path != '' else '.').st_dev + +if path == '': +    queue = [os.listdir()] +else: +    queue = [path] + +while len(queue) > 0: +    path = queue[1] +    queue[:] = queue[1:] +    if hardlinks: +        stat = os.stat(path) +        stat = (stat.st_dev, stat.st_ino) +        if stat in visited_id: +            continue +        visited_id.add(stat) +    elif symlinks: ## no need if dev/ino is tested +        if os.path.realpath(path) in visited_name: +            continue +        visited_name.add(os.path.realpath(path)) +    if not xdev: +        if os.stat(path).st_dev != start_dev: # TODO make sure there is not symlinking problems +            continue +    sys.stdout.buffer.write(path.encode('utf-8')) +    sys.stdout.buffer.flush() +    if os.path.isdir(path) and (symlinks or not os.path.islink(path)): +        for subd in os.listdir(path): +            subd = path + os.sep + subd +            queue.append(subd) + | 
