aboutsummaryrefslogtreecommitdiffstats
path: root/clip
blob: 8e4d3dd291487abc4a079418235b17b9f99e7921 (plain)
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
#!/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):
    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__':
    clipboard_filepath = '/dev/shm/%s-clipboard' % getpass.getuser()
    if(sys.stdin.isatty()):
        # Should write clipboard contents out to stdout
        with secure_open(clipboard_filepath, 'rb') as fo:
            sys.stdout.buffer.write(fo.read())
    elif(sys.stdout.isatty()):
        # Should save stdin to clipboard
        with secure_open(clipboard_filepath, 'wb') as fo:
            fo.write(sys.stdin.buffer.read())