-
Notifications
You must be signed in to change notification settings - Fork 0
/
gpgegrep.py
executable file
·73 lines (66 loc) · 2.29 KB
/
gpgegrep.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#!/usr/bin/env python3
from fcntl import flock, LOCK_EX
from lzma import LZMADecompressor
import os
from subprocess import Popen, DEVNULL, PIPE
import sys
lock_path = '/tmp/gpgegrep-lock-{uid}'.format(uid=os.getuid())
def main():
_, *grep_args, filename = sys.argv
grep_cmd = ['egrep'] + grep_args
gpg_cmd = ['gpg2', '--decrypt', '-o', '-', filename]
fl = open(lock_path, 'wb')
flock(fl, LOCK_EX)
grep_process = None
gpg_process = None
try:
grep_process = Popen(grep_cmd, stdin=PIPE)
gpg_process = Popen(gpg_cmd, stdin=DEVNULL, stdout=PIPE, stderr=DEVNULL)
head = b''
while True:
if grep_process.returncode is not None:
sys.exit('grep command has failed with returncode {}'.format(grep_process.returncode))
if gpg_process.returncode is not None:
sys.exit('GPG command has failed with returncode {}'.format(gpg_process.returncode))
buf = gpg_process.stdout.read(65536)
if buf == b'':
if head == b'':
sys.exit('Nothing received from gpg')
break
if fl is not None:
fl.close()
fl = None
if head is not None:
head += buf
if len(head) < 100:
continue
else:
if head.startswith(b'\xFD7zXZ\x00\x00'):
decompressor = LZMADecompressor()
else:
decompressor = None
buf = head
head = None
if decompressor is not None:
buf = decompressor.decompress(buf)
if decompressor.eof:
assert not decompressor.unused_data
try:
grep_process.stdin.write(buf)
except BrokenPipeError:
sys.exit(1)
gpg_process.wait()
grep_process.stdin.close()
grep_process.wait()
grep_process = None
finally:
if gpg_process:
gpg_process.terminate()
if grep_process:
grep_process.terminate()
if gpg_process:
gpg_process.wait()
if grep_process:
grep_process.wait()
if __name__ == '__main__':
main()