#!/usr/bin/python3 # SPDX-License-Identifier: MIT ''' Simple clipboard storing anything from stdin in a file or outputing from the file to stdout. Direction is determined from pipe redirection. Examples: Store something to clipboard: echo abc | clip Output clipboard content to console: clip Use content: clip > file clip | command ''' import contextlib import getpass import os import sys class Error(Exception): pass class SecurityError(Error): pass def fileno(filelike): if getattr(filelike, 'fileno'): return filelike.fileno() elif getattr(filelike, 'buffer'): return filelike.buffer.fileno() raise Error("fileno not found inside file-like object") @contextlib.contextmanager def secure_open(path, mode='r', *l, **kw): if os.path.islink(path): raise SecurityError("The clipboard file can not be a symlink") real_mode = mode if 'w' in real_mode: real_mode = real_mode.replace('w', 'a') with open(path, real_mode, *l, **kw) as fo: if os.fstat(fileno(fo)) != os.stat(path): raise SecurityError("Intrusion might have been done on %s" % path) if 'w' in mode: os.lseek(fileno(fo), 0, os.SEEK_SET) os.ftruncate(fileno(fo), 0) os.fchmod(fileno(fo), 0o600) yield fo if __name__ == '__main__': os.umask(0o077) clipboard_filepath = '/dev/shm/%s-clipboard' % getpass.getuser() if(sys.stdin.isatty()): # Should write clipboard contents out to stdout try: with secure_open(clipboard_filepath, 'rb') as fo: sys.stdout.buffer.write(fo.read()) except FileNotFoundError: # equivalent to an empty file pass elif(sys.stdout.isatty()): # Should save stdin to clipboard with secure_open(clipboard_filepath, 'wb') as fo: fo.write(sys.stdin.buffer.read())