Initial Contribution
diff --git a/import_tar.py b/import_tar.py
new file mode 100644
index 0000000..d7ce14d
--- /dev/null
+++ b/import_tar.py
@@ -0,0 +1,206 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import bz2
+import stat
+import tarfile
+import zlib
+import StringIO
+
+from import_ext import ImportExternal
+from error import ImportError
+
+class ImportTar(ImportExternal):
+  """Streams a (optionally compressed) tar file from the network
+     directly into a Project's Git repository.
+  """
+  @classmethod
+  def CanAccept(cls, url):
+    """Can this importer read and unpack the data stored at url?
+    """
+    if url.endswith('.tar.gz') or url.endswith('.tgz'):
+      return True
+    if url.endswith('.tar.bz2'):
+      return True
+    if url.endswith('.tar'):
+      return True
+    return False
+
+  def _UnpackFiles(self):
+    url_fd, url = self._OpenUrl()
+    try:
+      if url.endswith('.tar.gz') or url.endswith('.tgz'):
+        tar_fd = _Gzip(url_fd)
+      elif url.endswith('.tar.bz2'):
+        tar_fd = _Bzip2(url_fd)
+      elif url.endswith('.tar'):
+        tar_fd = _Raw(url_fd)
+      else:
+        raise ImportError('non-tar file extension: %s' % url)
+
+      try:
+        tar = tarfile.TarFile(name = url,
+                              mode = 'r',
+                              fileobj = tar_fd)
+        try:
+          for entry in tar:
+            mode = entry.mode
+
+            if (mode & 0170000) == 0:
+              if entry.isdir():
+                mode |= stat.S_IFDIR
+              elif entry.isfile() or entry.islnk():  # hard links as files
+                mode |= stat.S_IFREG
+              elif entry.issym():
+                mode |= stat.S_IFLNK
+
+            if stat.S_ISLNK(mode):   # symlink
+              data_fd = StringIO.StringIO(entry.linkname)
+              data_sz = len(entry.linkname)
+            elif stat.S_ISDIR(mode): # directory
+              data_fd = StringIO.StringIO('')
+              data_sz = 0
+            else:
+              data_fd = tar.extractfile(entry)
+              data_sz = entry.size
+
+            self._UnpackOneFile(mode, data_sz, entry.name, data_fd)
+        finally:
+          tar.close()
+      finally:
+        tar_fd.close()
+    finally:
+      url_fd.close()
+
+
+
+class _DecompressStream(object):
+  """file like object to decompress a tar stream
+  """
+  def __init__(self, fd):
+    self._fd = fd
+    self._pos = 0
+    self._buf = None
+
+  def tell(self):
+    return self._pos
+
+  def seek(self, offset):
+    d = offset - self._pos
+    if d > 0:
+      self.read(d)
+    elif d == 0:
+      pass
+    else:
+      raise NotImplementedError, 'seek backwards'
+
+  def close(self):
+    self._fd = None
+
+  def read(self, size = -1):
+    if not self._fd:
+      raise EOFError, 'Reached EOF'
+    
+    r = []
+    try:
+      if size >= 0:
+        self._ReadChunk(r, size)
+      else:
+        while True:
+          self._ReadChunk(r, 2048)
+    except EOFError:
+      pass
+
+    if len(r) == 1:
+      r = r[0]
+    else:
+      r = ''.join(r)
+    self._pos += len(r)
+    return r
+
+  def _ReadChunk(self, r, size):
+    b = self._buf
+    try:
+      while size > 0:
+        if b is None or len(b) == 0:
+          b = self._Decompress(self._fd.read(2048))
+          continue
+
+        use = min(size, len(b))
+        r.append(b[:use])
+        b = b[use:]
+        size -= use
+    finally:
+      self._buf = b
+
+  def _Decompress(self, b):
+    raise NotImplementedError, '_Decompress'
+
+
+class _Raw(_DecompressStream):
+  """file like object for an uncompressed stream
+  """
+  def __init__(self, fd):
+    _DecompressStream.__init__(self, fd)
+
+  def _Decompress(self, b):
+    return b
+
+
+class _Bzip2(_DecompressStream):
+  """file like object to decompress a .bz2 stream
+  """
+  def __init__(self, fd):
+    _DecompressStream.__init__(self, fd)
+    self._bz = bz2.BZ2Decompressor()
+
+  def _Decompress(self, b):
+    return self._bz.decompress(b)
+
+
+_FHCRC, _FEXTRA, _FNAME, _FCOMMENT = 2, 4, 8, 16
+class _Gzip(_DecompressStream):
+  """file like object to decompress a .gz stream
+  """
+  def __init__(self, fd):
+    _DecompressStream.__init__(self, fd)
+    self._z = zlib.decompressobj(-zlib.MAX_WBITS)
+
+    magic = fd.read(2)
+    if magic != '\037\213':
+      raise IOError, 'Not a gzipped file'
+
+    method = ord(fd.read(1))
+    if method != 8:
+      raise IOError, 'Unknown compression method'
+
+    flag = ord(fd.read(1))
+    fd.read(6)
+
+    if flag & _FEXTRA:
+      xlen = ord(fd.read(1))
+      xlen += 256 * ord(fd.read(1))
+      fd.read(xlen)
+    if flag & _FNAME:
+      while fd.read(1) != '\0':
+        pass
+    if flag & _FCOMMENT:
+      while fd.read(1) != '\0':
+        pass
+    if flag & _FHCRC:
+      fd.read(2)
+
+  def _Decompress(self, b):
+    return self._z.decompress(b)