##// END OF EJS Templates
py3: use '%d' for os.stat_result.st_nlink instead of '%s'...
Pulkit Goyal -
r38383:06c85cbd default
parent child Browse files
Show More
@@ -1,177 +1,177 b''
1 1 #!/usr/bin/env python
2 2
3 3 """
4 4 Utility for inspecting files in various ways.
5 5
6 6 This tool is like the collection of tools found in a unix environment but are
7 7 cross platform and stable and suitable for our needs in the test suite.
8 8
9 9 This can be used instead of tools like:
10 10 [
11 11 dd
12 12 find
13 13 head
14 14 hexdump
15 15 ls
16 16 md5sum
17 17 readlink
18 18 sha1sum
19 19 stat
20 20 tail
21 21 test
22 22 readlink.py
23 23 md5sum.py
24 24 """
25 25
26 26 from __future__ import absolute_import
27 27
28 28 import binascii
29 29 import glob
30 30 import hashlib
31 31 import optparse
32 32 import os
33 33 import re
34 34 import sys
35 35
36 36 # Python 3 adapters
37 37 ispy3 = (sys.version_info[0] >= 3)
38 38 if ispy3:
39 39 def iterbytes(s):
40 40 for i in range(len(s)):
41 41 yield s[i:i + 1]
42 42 else:
43 43 iterbytes = iter
44 44
45 45 def visit(opts, filenames, outfile):
46 46 """Process filenames in the way specified in opts, writing output to
47 47 outfile."""
48 48 for f in sorted(filenames):
49 49 isstdin = f == '-'
50 50 if not isstdin and not os.path.lexists(f):
51 51 outfile.write(b'%s: file not found\n' % f.encode('utf-8'))
52 52 continue
53 53 quiet = opts.quiet and not opts.recurse or isstdin
54 54 isdir = os.path.isdir(f)
55 55 islink = os.path.islink(f)
56 56 isfile = os.path.isfile(f) and not islink
57 57 dirfiles = None
58 58 content = None
59 59 facts = []
60 60 if isfile:
61 61 if opts.type:
62 62 facts.append(b'file')
63 63 if any((opts.hexdump, opts.dump, opts.md5, opts.sha1, opts.sha256)):
64 64 with open(f, 'rb') as fobj:
65 65 content = fobj.read()
66 66 elif islink:
67 67 if opts.type:
68 68 facts.append(b'link')
69 69 content = os.readlink(f)
70 70 elif isstdin:
71 71 content = getattr(sys.stdin, 'buffer', sys.stdin).read()
72 72 if opts.size:
73 73 facts.append(b'size=%d' % len(content))
74 74 elif isdir:
75 75 if opts.recurse or opts.type:
76 76 dirfiles = glob.glob(f + '/*')
77 77 facts.append(b'directory with %d files' % len(dirfiles))
78 78 elif opts.type:
79 79 facts.append(b'type unknown')
80 80 if not isstdin:
81 81 stat = os.lstat(f)
82 82 if opts.size and not isdir:
83 83 facts.append(b'size=%d' % stat.st_size)
84 84 if opts.mode and not islink:
85 85 facts.append(b'mode=%o' % (stat.st_mode & 0o777))
86 86 if opts.links:
87 facts.append(b'links=%s' % stat.st_nlink)
87 facts.append(b'links=%d' % stat.st_nlink)
88 88 if opts.newer:
89 89 # mtime might be in whole seconds so newer file might be same
90 90 if stat.st_mtime >= os.stat(opts.newer).st_mtime:
91 91 facts.append(b'newer than %s' % opts.newer)
92 92 else:
93 93 facts.append(b'older than %s' % opts.newer)
94 94 if opts.md5 and content is not None:
95 95 h = hashlib.md5(content)
96 96 facts.append(b'md5=%s' % binascii.hexlify(h.digest())[:opts.bytes])
97 97 if opts.sha1 and content is not None:
98 98 h = hashlib.sha1(content)
99 99 facts.append(b'sha1=%s' % binascii.hexlify(h.digest())[:opts.bytes])
100 100 if opts.sha256 and content is not None:
101 101 h = hashlib.sha256(content)
102 102 facts.append(b'sha256=%s' %
103 103 binascii.hexlify(h.digest())[:opts.bytes])
104 104 if isstdin:
105 105 outfile.write(b', '.join(facts) + b'\n')
106 106 elif facts:
107 107 outfile.write(b'%s: %s\n' % (f.encode('utf-8'), b', '.join(facts)))
108 108 elif not quiet:
109 109 outfile.write(b'%s:\n' % f.encode('utf-8'))
110 110 if content is not None:
111 111 chunk = content
112 112 if not islink:
113 113 if opts.lines:
114 114 if opts.lines >= 0:
115 115 chunk = b''.join(chunk.splitlines(True)[:opts.lines])
116 116 else:
117 117 chunk = b''.join(chunk.splitlines(True)[opts.lines:])
118 118 if opts.bytes:
119 119 if opts.bytes >= 0:
120 120 chunk = chunk[:opts.bytes]
121 121 else:
122 122 chunk = chunk[opts.bytes:]
123 123 if opts.hexdump:
124 124 for i in range(0, len(chunk), 16):
125 125 s = chunk[i:i + 16]
126 126 outfile.write(b'%04x: %-47s |%s|\n' %
127 127 (i, b' '.join(
128 128 b'%02x' % ord(c) for c in iterbytes(s)),
129 129 re.sub(b'[^ -~]', b'.', s)))
130 130 if opts.dump:
131 131 if not quiet:
132 132 outfile.write(b'>>>\n')
133 133 outfile.write(chunk)
134 134 if not quiet:
135 135 if chunk.endswith(b'\n'):
136 136 outfile.write(b'<<<\n')
137 137 else:
138 138 outfile.write(b'\n<<< no trailing newline\n')
139 139 if opts.recurse and dirfiles:
140 140 assert not isstdin
141 141 visit(opts, dirfiles, outfile)
142 142
143 143 if __name__ == "__main__":
144 144 parser = optparse.OptionParser("%prog [options] [filenames]")
145 145 parser.add_option("-t", "--type", action="store_true",
146 146 help="show file type (file or directory)")
147 147 parser.add_option("-m", "--mode", action="store_true",
148 148 help="show file mode")
149 149 parser.add_option("-l", "--links", action="store_true",
150 150 help="show number of links")
151 151 parser.add_option("-s", "--size", action="store_true",
152 152 help="show size of file")
153 153 parser.add_option("-n", "--newer", action="store",
154 154 help="check if file is newer (or same)")
155 155 parser.add_option("-r", "--recurse", action="store_true",
156 156 help="recurse into directories")
157 157 parser.add_option("-S", "--sha1", action="store_true",
158 158 help="show sha1 hash of the content")
159 159 parser.add_option("", "--sha256", action="store_true",
160 160 help="show sha256 hash of the content")
161 161 parser.add_option("-M", "--md5", action="store_true",
162 162 help="show md5 hash of the content")
163 163 parser.add_option("-D", "--dump", action="store_true",
164 164 help="dump file content")
165 165 parser.add_option("-H", "--hexdump", action="store_true",
166 166 help="hexdump file content")
167 167 parser.add_option("-B", "--bytes", type="int",
168 168 help="number of characters to dump")
169 169 parser.add_option("-L", "--lines", type="int",
170 170 help="number of lines to dump")
171 171 parser.add_option("-q", "--quiet", action="store_true",
172 172 help="no default output")
173 173 (opts, filenames) = parser.parse_args(sys.argv[1:])
174 174 if not filenames:
175 175 filenames = ['-']
176 176
177 177 visit(opts, filenames, getattr(sys.stdout, 'buffer', sys.stdout))
General Comments 0
You need to be logged in to leave comments. Login now