1 #!/usr/bin/env python 2 3 """CaptureCmd - A generic tool for capturing information about the 4 invocations of another program. 5 6 Usage 7 -- 8 1. Move the original tool to a safe known location. 9 10 2. Link CaptureCmd to the original tool's location. 11 12 3. Define CAPTURE_CMD_PROGRAM to the known location of the original 13 tool; this must be an absolute path. 14 15 4. Define CAPTURE_CMD_DIR to a directory to write invocation 16 information to. 17 """ 18 19 import hashlib 20 import os 21 import sys 22 import time 23 24 def saveCaptureData(prefix, dir, object): 25 string = repr(object) + '\n' 26 key = hashlib.sha1(string).hexdigest() 27 path = os.path.join(dir, 28 prefix + key) 29 if not os.path.exists(path): 30 f = open(path, 'wb') 31 f.write(string) 32 f.close() 33 return prefix + key 34 35 def main(): 36 program = os.getenv('CAPTURE_CMD_PROGRAM') 37 dir = os.getenv('CAPTURE_CMD_DIR') 38 fallback = os.getenv('CAPTURE_CMD_FALLBACK') 39 if not program: 40 raise ValueError('CAPTURE_CMD_PROGRAM is not defined!') 41 if not dir: 42 raise ValueError('CAPTURE_CMD_DIR is not defined!') 43 44 # Make the output directory if it doesn't already exist. 45 if not os.path.exists(dir): 46 os.mkdir(dir, 0700) 47 48 # Get keys for various data. 49 env = os.environ.items() 50 env.sort() 51 envKey = saveCaptureData('env-', dir, env) 52 cwdKey = saveCaptureData('cwd-', dir, os.getcwd()) 53 argvKey = saveCaptureData('argv-', dir, sys.argv) 54 entry = (time.time(), envKey, cwdKey, argvKey) 55 saveCaptureData('cmd-', dir, entry) 56 57 if fallback: 58 pid = os.fork() 59 if not pid: 60 os.execv(program, sys.argv) 61 os._exit(1) 62 else: 63 res = os.waitpid(pid, 0) 64 if not res: 65 os.execv(fallback, sys.argv) 66 os._exit(1) 67 os._exit(res) 68 else: 69 os.execv(program, sys.argv) 70 os._exit(1) 71 72 if __name__ == '__main__': 73 main() 74