1ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot"""Various tools used by MIME-reading or MIME-writing programs."""
2ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
3ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
4ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotimport os
5ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotimport sys
6ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotimport tempfile
7ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotfrom warnings import filterwarnings, catch_warnings
8ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotwith catch_warnings():
9ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    if sys.py3kwarning:
10ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        filterwarnings("ignore", ".*rfc822 has been removed", DeprecationWarning)
11ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    import rfc822
12ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
13ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotfrom warnings import warnpy3k
14ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotwarnpy3k("in 3.x, mimetools has been removed in favor of the email package",
15ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot         stacklevel=2)
16ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
17ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot__all__ = ["Message","choose_boundary","encode","decode","copyliteral",
18ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot           "copybinary"]
19ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
20ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotclass Message(rfc822.Message):
21ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """A derived class of rfc822.Message that knows about MIME headers and
22ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    contains some hooks for decoding encoded and multipart messages."""
23ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
24ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def __init__(self, fp, seekable = 1):
25ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        rfc822.Message.__init__(self, fp, seekable)
26ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.encodingheader = \
27ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                self.getheader('content-transfer-encoding')
28ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.typeheader = \
29ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                self.getheader('content-type')
30ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.parsetype()
31ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.parseplist()
32ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
33ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def parsetype(self):
34ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        str = self.typeheader
35ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if str is None:
36ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            str = 'text/plain'
37ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if ';' in str:
38ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            i = str.index(';')
39ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self.plisttext = str[i:]
40ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            str = str[:i]
41ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        else:
42ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self.plisttext = ''
43ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        fields = str.split('/')
44ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for i in range(len(fields)):
45ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            fields[i] = fields[i].strip().lower()
46ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.type = '/'.join(fields)
47ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.maintype = fields[0]
48ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.subtype = '/'.join(fields[1:])
49ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
50ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def parseplist(self):
51ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        str = self.plisttext
52ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        self.plist = []
53ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        while str[:1] == ';':
54ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            str = str[1:]
55ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if ';' in str:
56ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                # XXX Should parse quotes!
57ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                end = str.index(';')
58ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            else:
59ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                end = len(str)
60ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            f = str[:end]
61ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if '=' in f:
62ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                i = f.index('=')
63ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                f = f[:i].strip().lower() + \
64ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                        '=' + f[i+1:].strip()
65ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            self.plist.append(f.strip())
66ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            str = str[end:]
67ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
68ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def getplist(self):
69ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return self.plist
70ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
71ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def getparam(self, name):
72ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        name = name.lower() + '='
73ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        n = len(name)
74ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for p in self.plist:
75ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if p[:n] == name:
76ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                return rfc822.unquote(p[n:])
77ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return None
78ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
79ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def getparamnames(self):
80ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        result = []
81ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        for p in self.plist:
82ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            i = p.find('=')
83ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            if i >= 0:
84ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot                result.append(p[:i].lower())
85ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return result
86ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
87ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def getencoding(self):
88ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if self.encodingheader is None:
89ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            return '7bit'
90ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return self.encodingheader.lower()
91ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
92ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def gettype(self):
93ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return self.type
94ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
95ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def getmaintype(self):
96ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return self.maintype
97ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
98ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    def getsubtype(self):
99ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return self.subtype
100ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
101ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
102ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
103ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
104ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# Utility functions
105ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# -----------------
106ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
107ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robottry:
108ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    import thread
109ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotexcept ImportError:
110ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    import dummy_thread as thread
111ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot_counter_lock = thread.allocate_lock()
112ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotdel thread
113ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
114ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot_counter = 0
115ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotdef _get_next_counter():
116ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    global _counter
117ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    _counter_lock.acquire()
118ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    _counter += 1
119ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    result = _counter
120ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    _counter_lock.release()
121ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    return result
122ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
123ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot_prefix = None
124ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
125ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotdef choose_boundary():
126ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """Return a string usable as a multipart boundary.
127ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
128ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    The string chosen is unique within a single program run, and
129ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    incorporates the user id (if available), process id (if available),
130ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    and current time.  So it's very unlikely the returned string appears
131ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    in message text, but there's no guarantee.
132ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
133ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    The boundary contains dots so you have to quote it in the header."""
134ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
135ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    global _prefix
136ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    import time
137ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    if _prefix is None:
138ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        import socket
139ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        try:
140ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            hostid = socket.gethostbyname(socket.gethostname())
141ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        except socket.gaierror:
142ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            hostid = '127.0.0.1'
143ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        try:
144ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            uid = repr(os.getuid())
145ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        except AttributeError:
146ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            uid = '1'
147ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        try:
148ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            pid = repr(os.getpid())
149ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        except AttributeError:
150ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot            pid = '1'
151ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        _prefix = hostid + '.' + uid + '.' + pid
152ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    return "%s.%.3f.%d" % (_prefix, time.time(), _get_next_counter())
153ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
154ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
155ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# Subroutines for decoding some common content-transfer-types
156ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
157ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotdef decode(input, output, encoding):
158ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """Decode common content-transfer-encodings (base64, quopri, uuencode)."""
159ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    if encoding == 'base64':
160ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        import base64
161ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return base64.decode(input, output)
162ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    if encoding == 'quoted-printable':
163ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        import quopri
164ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return quopri.decode(input, output)
165ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    if encoding in ('uuencode', 'x-uuencode', 'uue', 'x-uue'):
166ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        import uu
167ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return uu.decode(input, output)
168ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    if encoding in ('7bit', '8bit'):
169ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return output.write(input.read())
170ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    if encoding in decodetab:
171ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        pipethrough(input, decodetab[encoding], output)
172ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    else:
173ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        raise ValueError, \
174ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot              'unknown Content-Transfer-Encoding: %s' % encoding
175ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
176ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotdef encode(input, output, encoding):
177ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    """Encode common content-transfer-encodings (base64, quopri, uuencode)."""
178ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    if encoding == 'base64':
179ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        import base64
180ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return base64.encode(input, output)
181ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    if encoding == 'quoted-printable':
182ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        import quopri
183ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return quopri.encode(input, output, 0)
184ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    if encoding in ('uuencode', 'x-uuencode', 'uue', 'x-uue'):
185ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        import uu
186ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return uu.encode(input, output)
187ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    if encoding in ('7bit', '8bit'):
188ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        return output.write(input.read())
189ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    if encoding in encodetab:
190ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        pipethrough(input, encodetab[encoding], output)
191ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    else:
192ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        raise ValueError, \
193ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot              'unknown Content-Transfer-Encoding: %s' % encoding
194ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
195ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# The following is no longer used for standard encodings
196ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
197ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot# XXX This requires that uudecode and mmencode are in $PATH
198ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
199ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotuudecode_pipe = '''(
200ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team RobotTEMP=/tmp/@uu.$$
201ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotsed "s%^begin [0-7][0-7]* .*%begin 600 $TEMP%" | uudecode
202ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotcat $TEMP
203ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotrm $TEMP
204ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot)'''
205ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
206ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotdecodetab = {
207ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        'uuencode':             uudecode_pipe,
208ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        'x-uuencode':           uudecode_pipe,
209ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        'uue':                  uudecode_pipe,
210ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        'x-uue':                uudecode_pipe,
211ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        'quoted-printable':     'mmencode -u -q',
212ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        'base64':               'mmencode -u -b',
213ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot}
214ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
215ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotencodetab = {
216ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        'x-uuencode':           'uuencode tempfile',
217ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        'uuencode':             'uuencode tempfile',
218ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        'x-uue':                'uuencode tempfile',
219ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        'uue':                  'uuencode tempfile',
220ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        'quoted-printable':     'mmencode -q',
221ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        'base64':               'mmencode -b',
222ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot}
223ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
224ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotdef pipeto(input, command):
225ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    pipe = os.popen(command, 'w')
226ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    copyliteral(input, pipe)
227ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    pipe.close()
228ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
229ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotdef pipethrough(input, command, output):
230ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    (fd, tempname) = tempfile.mkstemp()
231ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    temp = os.fdopen(fd, 'w')
232ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    copyliteral(input, temp)
233ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    temp.close()
234ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    pipe = os.popen(command + ' <' + tempname, 'r')
235ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    copybinary(pipe, output)
236ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    pipe.close()
237ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    os.unlink(tempname)
238ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
239ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotdef copyliteral(input, output):
240ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    while 1:
241ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        line = input.readline()
242ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if not line: break
243ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        output.write(line)
244ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot
245ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robotdef copybinary(input, output):
246ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    BUFSIZE = 8192
247ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot    while 1:
248ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        line = input.read(BUFSIZE)
249ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        if not line: break
250ec1a0b3abe08fb9a3952e8f48231cda1f6d9b1fandroid-build-team Robot        output.write(line)
251