| #!/usr/bin/env python | |
| """CaptureCmd - A generic tool for capturing information about the | |
| invocations of another program. | |
| Usage | |
| -- | |
| 1. Move the original tool to a safe known location. | |
| 2. Link CaptureCmd to the original tool's location. | |
| 3. Define CAPTURE_CMD_PROGRAM to the known location of the original | |
| tool; this must be an absolute path. | |
| 4. Define CAPTURE_CMD_DIR to a directory to write invocation | |
| information to. | |
| """ | |
| import hashlib | |
| import os | |
| import sys | |
| import time | |
| def saveCaptureData(prefix, dir, object): | |
| string = repr(object) + '\n' | |
| key = hashlib.sha1(string).hexdigest() | |
| path = os.path.join(dir, | |
| prefix + key) | |
| if not os.path.exists(path): | |
| f = open(path, 'wb') | |
| f.write(string) | |
| f.close() | |
| return prefix + key | |
| def main(): | |
| program = os.getenv('CAPTURE_CMD_PROGRAM') | |
| dir = os.getenv('CAPTURE_CMD_DIR') | |
| fallback = os.getenv('CAPTURE_CMD_FALLBACK') | |
| if not program: | |
| raise ValueError('CAPTURE_CMD_PROGRAM is not defined!') | |
| if not dir: | |
| raise ValueError('CAPTURE_CMD_DIR is not defined!') | |
| # Make the output directory if it doesn't already exist. | |
| if not os.path.exists(dir): | |
| os.mkdir(dir, 0700) | |
| # Get keys for various data. | |
| env = os.environ.items() | |
| env.sort() | |
| envKey = saveCaptureData('env-', dir, env) | |
| cwdKey = saveCaptureData('cwd-', dir, os.getcwd()) | |
| argvKey = saveCaptureData('argv-', dir, sys.argv) | |
| entry = (time.time(), envKey, cwdKey, argvKey) | |
| saveCaptureData('cmd-', dir, entry) | |
| if fallback: | |
| pid = os.fork() | |
| if not pid: | |
| os.execv(program, sys.argv) | |
| os._exit(1) | |
| else: | |
| res = os.waitpid(pid, 0) | |
| if not res: | |
| os.execv(fallback, sys.argv) | |
| os._exit(1) | |
| os._exit(res) | |
| else: | |
| os.execv(program, sys.argv) | |
| os._exit(1) | |
| if __name__ == '__main__': | |
| main() |