github.com/grumpyhome/grumpy@v0.3.1-0.20201208125205-7b775405bdf1/grumpy-runtime-src/third_party/stdlib/uu.py (about)

     1  #! /usr/bin/env python
     2  
     3  # Copyright 1994 by Lance Ellinghouse
     4  # Cathedral City, California Republic, United States of America.
     5  #                        All Rights Reserved
     6  # Permission to use, copy, modify, and distribute this software and its
     7  # documentation for any purpose and without fee is hereby granted,
     8  # provided that the above copyright notice appear in all copies and that
     9  # both that copyright notice and this permission notice appear in
    10  # supporting documentation, and that the name of Lance Ellinghouse
    11  # not be used in advertising or publicity pertaining to distribution
    12  # of the software without specific, written prior permission.
    13  # LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO
    14  # THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
    15  # FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE CENTRUM BE LIABLE
    16  # FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    17  # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    18  # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
    19  # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    20  #
    21  # Modified by Jack Jansen, CWI, July 1995:
    22  # - Use binascii module to do the actual line-by-line conversion
    23  #   between ascii and binary. This results in a 1000-fold speedup. The C
    24  #   version is still 5 times faster, though.
    25  # - Arguments more compliant with python standard
    26  
    27  """Implementation of the UUencode and UUdecode functions.
    28  
    29  encode(in_file, out_file [,name, mode])
    30  decode(in_file [, out_file, mode])
    31  """
    32  
    33  import binascii
    34  import os
    35  import sys
    36  
    37  __all__ = ["Error", "encode", "decode"]
    38  
    39  class Error(Exception):
    40      pass
    41  
    42  def encode(in_file, out_file, name=None, mode=None):
    43      """Uuencode file"""
    44      #
    45      # If in_file is a pathname open it and change defaults
    46      #
    47      opened_files = []
    48      try:
    49          if in_file == '-':
    50              in_file = sys.stdin
    51          elif isinstance(in_file, basestring):
    52              if name is None:
    53                  name = os.path.basename(in_file)
    54              if mode is None:
    55                  try:
    56                      mode = os.stat(in_file).st_mode
    57                  except AttributeError:
    58                      pass
    59              in_file = open(in_file, 'rb')
    60              opened_files.append(in_file)
    61          #
    62          # Open out_file if it is a pathname
    63          #
    64          if out_file == '-':
    65              out_file = sys.stdout
    66          elif isinstance(out_file, basestring):
    67              out_file = open(out_file, 'wb')
    68              opened_files.append(out_file)
    69          #
    70          # Set defaults for name and mode
    71          #
    72          if name is None:
    73              name = '-'
    74          if mode is None:
    75              mode = 0666
    76          #
    77          # Write the data
    78          #
    79          out_file.write('begin %o %s\n' % ((mode&0777),name))
    80          data = in_file.read(45)
    81          while len(data) > 0:
    82              out_file.write(binascii.b2a_uu(data))
    83              data = in_file.read(45)
    84          out_file.write(' \nend\n')
    85      finally:
    86          for f in opened_files:
    87              f.close()
    88  
    89  
    90  def decode(in_file, out_file=None, mode=None, quiet=0):
    91      """Decode uuencoded file"""
    92      #
    93      # Open the input file, if needed.
    94      #
    95      opened_files = []
    96      if in_file == '-':
    97          in_file = sys.stdin
    98      elif isinstance(in_file, basestring):
    99          in_file = open(in_file)
   100          opened_files.append(in_file)
   101      try:
   102          #
   103          # Read until a begin is encountered or we've exhausted the file
   104          #
   105          while True:
   106              hdr = in_file.readline()
   107              if not hdr:
   108                  raise Error('No valid begin line found in input file')
   109              if not hdr.startswith('begin'):
   110                  continue
   111              hdrfields = hdr.split(' ', 2)
   112              if len(hdrfields) == 3 and hdrfields[0] == 'begin':
   113                  try:
   114                      int(hdrfields[1], 8)
   115                      break
   116                  except ValueError:
   117                      pass
   118          if out_file is None:
   119              out_file = hdrfields[2].rstrip()
   120              if os.path.exists(out_file):
   121                  raise Error('Cannot overwrite existing file: %s' % out_file)
   122          if mode is None:
   123              mode = int(hdrfields[1], 8)
   124          #
   125          # Open the output file
   126          #
   127          if out_file == '-':
   128              out_file = sys.stdout
   129          elif isinstance(out_file, basestring):
   130              fp = open(out_file, 'wb')
   131              try:
   132                  os.path.chmod(out_file, mode)
   133              except AttributeError:
   134                  pass
   135              out_file = fp
   136              opened_files.append(out_file)
   137          #
   138          # Main decoding loop
   139          #
   140          s = in_file.readline()
   141          while s and s.strip() != 'end':
   142              try:
   143                  data = binascii.a2b_uu(s)
   144              except binascii.Error, v:
   145                  # Workaround for broken uuencoders by /Fredrik Lundh
   146                  nbytes = (((ord(s[0])-32) & 63) * 4 + 5) // 3
   147                  data = binascii.a2b_uu(s[:nbytes])
   148                  if not quiet:
   149                      sys.stderr.write("Warning: %s\n" % v)
   150              out_file.write(data)
   151              s = in_file.readline()
   152          if not s:
   153              raise Error('Truncated input file')
   154      finally:
   155          for f in opened_files:
   156              f.close()
   157  
   158  def test():
   159      """uuencode/uudecode main program"""
   160  
   161      import optparse
   162      parser = optparse.OptionParser(usage='usage: %prog [-d] [-t] [input [output]]')
   163      parser.add_option('-d', '--decode', dest='decode', help='Decode (instead of encode)?', default=False, action='store_true')
   164      parser.add_option('-t', '--text', dest='text', help='data is text, encoded format unix-compatible text?', default=False, action='store_true')
   165  
   166      (options, args) = parser.parse_args()
   167      if len(args) > 2:
   168          parser.error('incorrect number of arguments')
   169          sys.exit(1)
   170  
   171      input = sys.stdin
   172      output = sys.stdout
   173      if len(args) > 0:
   174          input = args[0]
   175      if len(args) > 1:
   176          output = args[1]
   177  
   178      if options.decode:
   179          if options.text:
   180              if isinstance(output, basestring):
   181                  output = open(output, 'w')
   182              else:
   183                  print sys.argv[0], ': cannot do -t to stdout'
   184                  sys.exit(1)
   185          decode(input, output)
   186      else:
   187          if options.text:
   188              if isinstance(input, basestring):
   189                  input = open(input, 'r')
   190              else:
   191                  print sys.argv[0], ': cannot do -t from stdin'
   192                  sys.exit(1)
   193          encode(input, output)
   194  
   195  if __name__ == '__main__':
   196      test()