#! /usr/bin/env python

# 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.
#
# Modified by Jack Jansen, CWI, July 1995:
# - Use binascii module to do the actual line-by-line conversion
#   between ascii and binary. This results in a 1000-fold speedup. The C
#   version is still 5 times faster, though.
# - Arguments more compliant with python standard
#
# This file implements the UUencode and UUdecode functions.

# encode(in_file, out_file [,name, mode])
# decode(in_file [, out_file, mode])

import binascii
import os
import string

Error = 'uu.Error'

def encode(in_file, out_file, name=None, mode=None):
    """Uuencode file"""
    #
    # If in_file is a pathname open it and change defaults
    #
    if in_file == '-':
	in_file = sys.stdin
    elif type(in_file) == type(''):
	if name == None:
	    name = os.path.basename(in_file)
	if mode == None:
	    try:
		mode = os.stat(in_file)[0]
	    except AttributeError:
		pass
	in_file = open(in_file, 'rb')
    #
    # Open out_file if it is a pathname
    #
    if out_file == '-':
	out_file = sys.stdout
    elif type(out_file) == type(''):
	out_file = open(out_file, 'w')
    #
    # Set defaults for name and mode
    #
    if name == None:
	name = '-'
    if mode == None:
	mode = 0666
    #
    # Write the data
    #
    out_file.write('begin %o %s\n' % ((mode&0777),name))
    str = in_file.read(45)
    while len(str) > 0:
	out_file.write(binascii.b2a_uu(str))
	str = in_file.read(45)
    out_file.write(' \nend\n')


def decode(in_file, out_file=None, mode=None):
    """Decode uuencoded file"""
    #
    # Open the input file, if needed.
    #
    if in_file == '-':
	in_file = sys.stdin
    elif type(in_file) == type(''):
	in_file = open(in_file)
    #
    # Read until a begin is encountered or we've exhausted the file
    #
    while 1:
	hdr = in_file.readline()
	if not hdr:
	    raise Error, 'No valid begin line found in input file'
	if hdr[:5] != 'begin':
	    continue
	hdrfields = string.split(hdr)
	if len(hdrfields) == 3 and hdrfields[0] == 'begin':
	    try:
		string.atoi(hdrfields[1], 8)
		break
	    except ValueError:
		pass
    if out_file == None:
	out_file = hdrfields[2]
    if mode == None:
	mode = string.atoi(hdrfields[1], 8)
    #
    # Open the output file
    #
    if out_file == '-':
	out_file = sys.stdout
    elif type(out_file) == type(''):
	fp = open(out_file, 'wb')
	try:
	    os.path.chmod(out_file, mode)
	except AttributeError:
	    pass
	out_file = fp
    #
    # Main decoding loop
    #
    str = in_file.readline()
    while str and str != 'end\n':
	out_file.write(binascii.a2b_uu(str))
	str = in_file.readline()
    if not str:
	raise Error, 'Truncated input file'

def test():
    """uuencode/uudecode main program"""
    import sys
    import getopt

    dopt = 0
    topt = 0
    input = sys.stdin
    output = sys.stdout
    ok = 1
    try:
	optlist, args = getopt.getopt(sys.argv[1:], 'dt')
    except getopt.error:
	ok = 0
    if not ok or len(args) > 2:
	print 'Usage:', sys.argv[0], '[-d] [-t] [input [output]]'
	print ' -d: Decode (in stead of encode)'
	print ' -t: data is text, encoded format unix-compatible text'
	sys.exit(1)
	
    for o, a in optlist:
	if o == '-d': dopt = 1
	if o == '-t': topt = 1

    if len(args) > 0:
	input = args[0]
    if len(args) > 1:
	output = args[1]

    if dopt:
	if topt:
	    if type(output) == type(''):
		output = open(output, 'w')
	    else:
		print sys.argv[0], ': cannot do -t to stdout'
		sys.exit(1)
	decode(input, output)
    else:
	if topt:
	    if type(input) == type(''):
		input = open(input, 'r')
	    else:
		print sys.argv[0], ': cannot do -t from stdin'
		sys.exit(1)
	encode(input, output)

if __name__ == '__main__':
    test()
