From 853474194fa799ab96a135f900332eaca52a07e7 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Fri, 9 Sep 1994 11:10:15 +0000 Subject: [PATCH] mhlib.py: delay opening of sequences file so we don't overwrite it when putsequences is called with a bad argument rfc822.py: better handling of dates with no or bad timezones uu.py: contributed by Lance -- uu{en,de}code --- Lib/mhlib.py | 13 ++- Lib/rfc822.py | 9 ++- Lib/uu.py | 214 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 233 insertions(+), 3 deletions(-) create mode 100755 Lib/uu.py diff --git a/Lib/mhlib.py b/Lib/mhlib.py index b24695cfebf..5bdda7220dd 100644 --- a/Lib/mhlib.py +++ b/Lib/mhlib.py @@ -36,6 +36,7 @@ # f.putsequences(dict) # write sequences back to folder # # m = f.openmessage(n) # new open message object (costs a file descriptor) +# m is a derived class of mimetools.Message(rfc822.Message), with: # s = m.getheadertext() # text of message's headers # s = m.getheadertext(pred) # text of message's headers, filtered by pred # s = m.getbodytext() # text of message's body, decoded @@ -299,11 +300,19 @@ class Folder: # Write the set of sequences back to the folder def putsequences(self, sequences): fullname = self.getsequencesfilename() - f = open(fullname, 'w') + f = None for key in sequences.keys(): s = IntSet('', ' ') s.fromlist(sequences[key]) + if not f: f = open(fullname, 'w') f.write('%s: %s\n' % (key, s.tostring())) + if not f: + try: + os.unlink(fullname) + except os.error: + pass + else: + f.close() # Return the current message. Raise KeyError when there is none def getcurrent(self): @@ -313,7 +322,7 @@ class Folder: def setcurrent(self, n): updateline(self.getsequencesfilename(), 'cur', str(n), 0) - # Open a message -- returns a mimetools.Message object + # Open a message -- returns a Message object def openmessage(self, n): path = self.getmessagefilename(n) return Message(self, n) diff --git a/Lib/rfc822.py b/Lib/rfc822.py index 886098ccf40..fcf31fbb970 100644 --- a/Lib/rfc822.py +++ b/Lib/rfc822.py @@ -329,11 +329,18 @@ _monthnames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] def parsedate(data): - # XXX This completely ignores timezone matters at the moment... + # XXX This still mostly ignores timezone matters at the moment... data = string.split(data) if data[0][-1] == ',': # There's a dayname here. Skip it del data[0] + if len(data) == 4: + s = data[3] + i = string.find(s, '+') + if i > 0: + data[3:] = [s[:i], s[i+1:]] + else: + data.append('') # Dummy tz if len(data) < 5: return None data = data[:5] diff --git a/Lib/uu.py b/Lib/uu.py new file mode 100755 index 00000000000..7f0783d1d2a --- /dev/null +++ b/Lib/uu.py @@ -0,0 +1,214 @@ +# uu.py +# Copyright 1994 by Lance Ellinghouse +# Cathedral City, California Republic, United States of America. +# All Rights Reserved +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose and without fee is hereby granted, +# provided that the above copyright notice appear in all copies and that +# both that copyright notice and this permission notice appear in +# supporting documentation, and that the name of Lance Ellinghouse +# not be used in advertising or publicity pertaining to distribution +# of the software without specific, written prior permission. +# LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO +# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE CENTRUM BE LIABLE +# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +# This file implements the UUencode and UUdecode functions. + +# encode(filename, mode, in_file, out_file) +# decode(filename, mode, in_file) +# decode(in_file, out_file) +# decode(in_file) + +# encode a single char to always be printable +def _ENC(ch): + if type(ch) == type(''): + a = ch[:1] # only 1 char + if len(a) == 0: + raise ValueError, 'need to pass in at least 1 char' + a = ord(a) + elif type(ch) == type(0): + a = ch + else: + raise TypeError, 'must pass in an integer or single character' + return chr((a & 077) + ord(' ')) + +# input 3 chars, output 4 encoded chars +def _outenc(str): + if len(str) > 3: + raise ValueError, 'can only accept strings of 3 chars' + p0, p1, p2 = 0, 0, 0 + if len(str) > 2: + p2 = ord(str[2]) + if len(str) > 1: + p1 = ord(str[1]) + if len(str) > 0: + p0 = ord(str[0]) + c1 = p0 >> 2 + c2 = (p0 << 4) & 060 | (p1 >> 4) & 017 + c3 = (p1 << 2) & 074 | (p2 >> 6) & 03 + c4 = p2 & 077 + rtn = _ENC(c1) + rtn = rtn + _ENC(c2) + rtn = rtn + _ENC(c3) + rtn = rtn + _ENC(c4) + return rtn + +# pass in 45 bytes max, returns 62 bytes encoded +def _encode(str): + if len(str) > 45: + raise ValueError, 'cannot handle more than 45 chars at once' + length = len(str) + rtn = _ENC(length) + i = 0 + while i < length: + rtn = rtn + _outenc(str[i:(i+3)]) + i = i + 3 + rtn = rtn + '\n' + return rtn + +# encode a fileobject and write out to a file object +def encode(filename, mode, in_file, out_file): + out_file.write('begin %o %s\n' % ((mode&0777),filename)) + str = in_file.read(45) + while len(str) > 0: + out_file.write(_encode(str)) + str = in_file.read(45) + out_file.write(' \nend\n') + return None + +# def decode a single char from printable to possibly non-printable +def _DEC(ch): + if type(ch) != type('') or len(ch) != 1: + raise ValueError, 'need to pass in a single char' + a = ord(ch[0:1]) + return (a - ord(' ')) + +# input 4 chars encoded, output 3 chars unencoded +def _outdec(str): + if len(str) > 4: + raise ValueError, 'can only accept strings of 4 chars' + p0, p1, p2, p3 = 0, 0, 0, 0 + if len(str) > 3: + p3 = _DEC(str[3]) + if len(str) > 2: + p2 = _DEC(str[2]) + if len(str) > 1: + p1 = _DEC(str[1]) + if len(str) > 0: + p0 = _DEC(str[0]) + c1 = p0 << 2 | (p1 & 060) >> 4 + c2 = (p1 & 017) << 4 | (p2 & 074) >> 2 + c3 = (p2 & 03) << 6 | (p3 & 077) + rtn = chr(c1) + rtn = rtn + chr(c2) + rtn = rtn + chr(c3) + return rtn + +# pass in 62 bytes and return 45 bytes unencoded +def _decode(str): + if len(str) > 62: + raise ValueError, 'cannot handle more than 62 chars at once' + length = _DEC(str[0]) + i = 1 + rtn = '' + while len(rtn) < length: + rtn = rtn + _outdec(str[i:(i+4)]) + i = i + 4 + return rtn[0:length] + +# decode(filename, mode, in_file) +# decode(in_file, out_file) +# decode(in_file) +def decode(*args): + ok = 1 + _setup = None + out_file = None + if len(args) == 3: + filename, mode, in_file = args + if type(filename) != type(''): + ok = 0 + if type(mode) != type(0): + ok = 0 + try: + _ = getattr(in_file,'readline') + except AttributeError: + ok = 0 + def _setup(out_file,args): + filename, mode, in_file = args + # open file as specified and assign out_file for later use + out_file = open(filename,'w',mode) + _out_file_orig = 0 + _ = in_file.readline() + return (out_file,_out_file_orig) + elif len(args) == 2: + in_file, out_file = args + try: + _ = getattr(in_file,'readline') + _ = getattr(out_file,'write') + except AttributeError: + ok = 0 + def _setup(out_file, args): + in_file, out_file = args + # Toss the 'begin mode filename' part.. not needed + _ = in_file.readline() + _out_file_orig = 1 + return (out_file,_out_file_orig) + elif len(args) == 1: + in_file = args[0] + try: + _ = getattr(in_file,'readline') + except AttributeError: + ok = 0 + def _setup(out_file, args): + import strop + in_file = args[0] + # open file as specified in uu file and + # assign out_file for later use + i = in_file.readline() + i = strop.strip(i) + if 'begin' != i[:5]: + raise IOError, 'input file not in UUencoded format' + [dummy, mode, filename] = strop.split(i) + mode = strop.atoi(mode, 8) + out_file = open(filename,'w',mode) + _out_file_orig = 0 + return (out_file,_out_file_orig) + if ok != 1: + raise SyntaxError, 'must be (filename, mode, in_file) or (in_file,out_file) or (in_file)' + out_file, _out_file_orig = _setup(out_file, args) + str = in_file.readline() + while len(str) > 0 and str != ' \n' and str != 'end\n': + out_file.write(_decode(str)) + str = in_file.readline() + if _out_file_orig == 0: + out_file.close() + del out_file + return None + +def test(): + import sys + if sys.argv[1:2] == ['-d']: + if sys.argv[2:]: + decode(open(sys.argv[2]), sys.stdout) + else: + decode(sys.stdin, sys.stdout) + elif sys.argv[1:2] == ['-e']: + if sys.argv[2:]: + file = sys.argv[2] + fp = open(file) + else: + file = '-' + fp = sys.stdin + encode(file, 0644, fp, sys.stdout) + else: + print 'usage: uu -d [file]; (to decode)' + print 'or: uu -e [file]; (to encode)' + sys.exit(2) + +if __name__ == '__main__': + test()