0001 #! /usr/bin/env python 0002 0003 # Copyright 1994 by Lance Ellinghouse 0004 # Cathedral City, California Republic, United States of America. 0005 # All Rights Reserved 0006 # Permission to use, copy, modify, and distribute this software and its 0007 # documentation for any purpose and without fee is hereby granted, 0008 # provided that the above copyright notice appear in all copies and that 0009 # both that copyright notice and this permission notice appear in 0010 # supporting documentation, and that the name of Lance Ellinghouse 0011 # not be used in advertising or publicity pertaining to distribution 0012 # of the software without specific, written prior permission. 0013 # LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO 0014 # THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 0015 # FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE CENTRUM BE LIABLE 0016 # FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 0017 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 0018 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 0019 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 0020 # 0021 # Modified by Jack Jansen, CWI, July 1995: 0022 # - Use binascii module to do the actual line-by-line conversion 0023 # between ascii and binary. This results in a 1000-fold speedup. The C 0024 # version is still 5 times faster, though. 0025 # - Arguments more compliant with python standard 0026 0027 """Implementation of the UUencode and UUdecode functions. 0028 0029 encode(in_file, out_file [,name, mode]) 0030 decode(in_file [, out_file, mode]) 0031 """ 0032 0033 import binascii 0034 import os 0035 import sys 0036 from types import StringType 0037 0038 __all__ = ["Error", "encode", "decode"] 0039 0040 class Error(Exception): 0041 pass 0042 0043 def encode(in_file, out_file, name=None, mode=None): 0044 """Uuencode file""" 0045 # 0046 # If in_file is a pathname open it and change defaults 0047 # 0048 if in_file == '-': 0049 in_file = sys.stdin 0050 elif isinstance(in_file, StringType): 0051 if name is None: 0052 name = os.path.basename(in_file) 0053 if mode is None: 0054 try: 0055 mode = os.stat(in_file).st_mode 0056 except AttributeError: 0057 pass 0058 in_file = open(in_file, 'rb') 0059 # 0060 # Open out_file if it is a pathname 0061 # 0062 if out_file == '-': 0063 out_file = sys.stdout 0064 elif isinstance(out_file, StringType): 0065 out_file = open(out_file, 'w') 0066 # 0067 # Set defaults for name and mode 0068 # 0069 if name is None: 0070 name = '-' 0071 if mode is None: 0072 mode = 0666 0073 # 0074 # Write the data 0075 # 0076 out_file.write('begin %o %s\n' % ((mode&0777),name)) 0077 str = in_file.read(45) 0078 while len(str) > 0: 0079 out_file.write(binascii.b2a_uu(str)) 0080 str = in_file.read(45) 0081 out_file.write(' \nend\n') 0082 0083 0084 def decode(in_file, out_file=None, mode=None, quiet=0): 0085 """Decode uuencoded file""" 0086 # 0087 # Open the input file, if needed. 0088 # 0089 if in_file == '-': 0090 in_file = sys.stdin 0091 elif isinstance(in_file, StringType): 0092 in_file = open(in_file) 0093 # 0094 # Read until a begin is encountered or we've exhausted the file 0095 # 0096 while 1: 0097 hdr = in_file.readline() 0098 if not hdr: 0099 raise Error, 'No valid begin line found in input file' 0100 if hdr[:5] != 'begin': 0101 continue 0102 hdrfields = hdr.split(" ", 2) 0103 if len(hdrfields) == 3 and hdrfields[0] == 'begin': 0104 try: 0105 int(hdrfields[1], 8) 0106 break 0107 except ValueError: 0108 pass 0109 if out_file is None: 0110 out_file = hdrfields[2].rstrip() 0111 if os.path.exists(out_file): 0112 raise Error, 'Cannot overwrite existing file: %s' % out_file 0113 if mode is None: 0114 mode = int(hdrfields[1], 8) 0115 # 0116 # Open the output file 0117 # 0118 if out_file == '-': 0119 out_file = sys.stdout 0120 elif isinstance(out_file, StringType): 0121 fp = open(out_file, 'wb') 0122 try: 0123 os.path.chmod(out_file, mode) 0124 except AttributeError: 0125 pass 0126 out_file = fp 0127 # 0128 # Main decoding loop 0129 # 0130 s = in_file.readline() 0131 while s and s.strip() != 'end': 0132 try: 0133 data = binascii.a2b_uu(s) 0134 except binascii.Error, v: 0135 # Workaround for broken uuencoders by /Fredrik Lundh 0136 nbytes = (((ord(s[0])-32) & 63) * 4 + 5) / 3 0137 data = binascii.a2b_uu(s[:nbytes]) 0138 if not quiet: 0139 sys.stderr.write("Warning: %s\n" % str(v)) 0140 out_file.write(data) 0141 s = in_file.readline() 0142 if not s: 0143 raise Error, 'Truncated input file' 0144 0145 def test(): 0146 """uuencode/uudecode main program""" 0147 import getopt 0148 0149 dopt = 0 0150 topt = 0 0151 input = sys.stdin 0152 output = sys.stdout 0153 ok = 1 0154 try: 0155 optlist, args = getopt.getopt(sys.argv[1:], 'dt') 0156 except getopt.error: 0157 ok = 0 0158 if not ok or len(args) > 2: 0159 print 'Usage:', sys.argv[0], '[-d] [-t] [input [output]]' 0160 print ' -d: Decode (in stead of encode)' 0161 print ' -t: data is text, encoded format unix-compatible text' 0162 sys.exit(1) 0163 0164 for o, a in optlist: 0165 if o == '-d': dopt = 1 0166 if o == '-t': topt = 1 0167 0168 if len(args) > 0: 0169 input = args[0] 0170 if len(args) > 1: 0171 output = args[1] 0172 0173 if dopt: 0174 if topt: 0175 if isinstance(output, StringType): 0176 output = open(output, 'w') 0177 else: 0178 print sys.argv[0], ': cannot do -t to stdout' 0179 sys.exit(1) 0180 decode(input, output) 0181 else: 0182 if topt: 0183 if isinstance(input, StringType): 0184 input = open(input, 'r') 0185 else: 0186 print sys.argv[0], ': cannot do -t from stdin' 0187 sys.exit(1) 0188 encode(input, output) 0189 0190 if __name__ == '__main__': 0191 test() 0192
Generated by PyXR 0.9.4