#! /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()
