text: # 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.
  #
  # 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 the header line, and fill in optional args if needed
      #
      hdr = in_file.readline()
      if not hdr:
  	raise Error, 'Empty input file'
      hdrfields = string.split(hdr)
      if len(hdrfields) <> 3 or hdrfields[0] <> 'begin':
  	raise Error, ('Incorrect uu header line', hdr)
      if out_file == None:
  	out_file = hdrfields[2]
      if mode == None:
  	mode = string.atoi(hdrfields[1])
      #
      # 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()
  