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