aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2013-10-08 11:10:49 +0200
committerMattias Andrée <maandree@operamail.com>2013-10-08 11:10:49 +0200
commit10d5a6637c5945639743a0a22b8e9ac0b1a5e156 (patch)
tree13b4d47fcca0bf73155adce6a5335190cd0dbff6
parentchange language (diff)
downloadbfind-10d5a6637c5945639743a0a22b8e9ac0b1a5e156.tar.gz
bfind-10d5a6637c5945639743a0a22b8e9ac0b1a5e156.tar.bz2
bfind-10d5a6637c5945639743a0a22b8e9ac0b1a5e156.tar.xz
draft
Signed-off-by: Mattias Andrée <maandree@operamail.com>
-rw-r--r--README7
-rwxr-xr-xsrc/bfind.py69
2 files changed, 72 insertions, 4 deletions
diff --git a/README b/README
index 2c887f9..e86951b 100644
--- a/README
+++ b/README
@@ -2,7 +2,7 @@ Minimalitic `find` using breadth first crawling.
The entire invocation syntax is:
- bfind [--xdev] [--hardlinks] [--symlinks] DIRECTORY
+ bfind [--xdev] [--hardlinks] [--symlinks] [--] DIRECTORY
With --xdev crawling will not be restricted to
one mount point.
@@ -13,7 +13,7 @@ on directories.
With --symlinks, bfind will visit directories
symlinks points, and directories will never
be revisited. Visited directories will be
-memorised by absolute path name.
+memorised by absolute real path name.
Short option alternatives:
@@ -25,6 +25,5 @@ Short option alternatives:
Short options can be combined
-Each link will always start with DIRECTORY
-and always and with a /.
+Each link will always start with DIRECTORY.
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)
+