# Copyright 2001-2004 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Id$


# The format for a tbz2/xpak:
#
#  tbz2: tar.bz2 + xpak + (xpak_offset) + "STOP"
#  xpak: "XPAKPACK" + (index_len) + (data_len) + index + data + "XPAKSTOP"
# index: (pathname_len) + pathname + (data_offset) + (data_len)
#        index entries are concatenated end-to-end.
#  data: concatenated data chunks, end-to-end.
#
# [tarball]XPAKPACKIIIIDDDD[index][data]XPAKSTOPOOOOSTOP
#
# (integer) == encodeint(integer)  ===> 4 characters (big-endian copy)
# '+' means concatenate the fields ===> All chunks are strings

import sys,os,shutil,errno
from stat import *

def addtolist(mylist,curdir):
	"""(list, dir) --- Takes an array(list) and appends all files from dir down
	the directory tree. Returns nothing. list is modified."""
	for x in os.listdir("."):
		if os.path.isdir(x):
			os.chdir(x)
			addtolist(mylist,curdir+x+"/")
			os.chdir("..")
		else:
			if curdir+x not in mylist:
				mylist.append(curdir+x)

def encodeint(myint):
	"""Takes a 4 byte integer and converts it into a string of 4 characters.
	Returns the characters in a string."""
	part1=chr((myint >> 24 ) & 0x000000ff)
	part2=chr((myint >> 16 ) & 0x000000ff)
	part3=chr((myint >> 8 ) & 0x000000ff)
	part4=chr(myint & 0x000000ff)
	return part1+part2+part3+part4

def decodeint(mystring):
	"""Takes a 4 byte string and converts it into a 4 byte integer.
	Returns an integer."""
	myint=0
	myint=myint+ord(mystring[3])
	myint=myint+(ord(mystring[2]) << 8)
	myint=myint+(ord(mystring[1]) << 16)
	myint=myint+(ord(mystring[0]) << 24)
	return myint

def xpak(rootdir,outfile=None):
	"""(rootdir,outfile) -- creates an xpak segment of the directory 'rootdir'
	and under the name 'outfile' if it is specified. Otherwise it returns the
	xpak segment."""
	try:
		origdir=os.getcwd()
	except SystemExit, e:
		raise
	except:
		os.chdir("/")
		origdir="/"
	os.chdir(rootdir)
	mylist=[]

	addtolist(mylist,"")
	mylist.sort()
	mydata = {}
	for x in mylist:
		a = open(x, "r")
		mydata[x] = a.read()
		a.close()
	os.chdir(origdir)

	xpak_segment = xpak_mem(mydata)
	if outfile:
		outf = open(outfile, "w")
		outf.write(xpak_segment)
		outf.close()
	else:
		return xpak_segment

def xpak_mem(mydata):
	"""Create an xpack segement from a map object."""
	indexglob=""
	indexpos=0
	dataglob=""
	datapos=0
	for x, newglob in mydata.iteritems():
		mydatasize=len(newglob)
		indexglob=indexglob+encodeint(len(x))+x+encodeint(datapos)+encodeint(mydatasize)
		indexpos=indexpos+4+len(x)+4+4
		dataglob=dataglob+newglob
		datapos=datapos+mydatasize
	return "XPAKPACK" \
	+ encodeint(len(indexglob)) \
	+ encodeint(len(dataglob)) \
	+ indexglob \
	+ dataglob \
	+ "XPAKSTOP"

def xsplit(infile):
	"""(infile) -- Splits the infile into two files.
	'infile.index' contains the index segment.
	'infile.dat' contails the data segment."""
	myfile=open(infile,"r")
	mydat=myfile.read()
	myfile.close()
	
	splits = xsplit_mem(mydat)
	if not splits:
		return False
	
	myfile=open(infile+".index","w")
	myfile.write(splits[0])
	myfile.close()
	myfile=open(infile+".dat","w")
	myfile.write(splits[1])
	myfile.close()
	return True

def xsplit_mem(mydat):
	if mydat[0:8]!="XPAKPACK":
		return None
	if mydat[-8:]!="XPAKSTOP":
		return None
	indexsize=decodeint(mydat[8:12])
	return (mydat[16:indexsize+16], mydat[indexsize+16:-8])

def getindex(infile):
	"""(infile) -- grabs the index segment from the infile and returns it."""
	myfile=open(infile,"r")
	myheader=myfile.read(16)
	if myheader[0:8]!="XPAKPACK":
		myfile.close()
		return
	indexsize=decodeint(myheader[8:12])
	myindex=myfile.read(indexsize)
	myfile.close()
	return myindex

def getboth(infile):
	"""(infile) -- grabs the index and data segments from the infile.
	Returns an array [indexSegment,dataSegment]"""
	myfile=open(infile,"r")
	myheader=myfile.read(16)
	if myheader[0:8]!="XPAKPACK":
		myfile.close()
		return
	indexsize=decodeint(myheader[8:12])
	datasize=decodeint(myheader[12:16])
	myindex=myfile.read(indexsize)
	mydata=myfile.read(datasize)
	myfile.close()
	return myindex, mydata

def listindex(myindex):
	"""Print to the terminal the filenames listed in the indexglob passed in."""
	for x in getindex_mem(myindex):
		print x

def getindex_mem(myindex):
	"""Returns the filenames listed in the indexglob passed in."""
	myindexlen=len(myindex)
	startpos=0
	myret=[]
	while ((startpos+8)<myindexlen):
		mytestlen=decodeint(myindex[startpos:startpos+4])
		myret=myret+[myindex[startpos+4:startpos+4+mytestlen]]
		startpos=startpos+mytestlen+12
	return myret

def searchindex(myindex,myitem):
	"""(index,item) -- Finds the offset and length of the file 'item' in the
	datasegment via the index 'index' provided."""
	mylen=len(myitem)
	myindexlen=len(myindex)
	startpos=0
	while ((startpos+8)<myindexlen):
		mytestlen=decodeint(myindex[startpos:startpos+4])
		if mytestlen==mylen:
			if myitem==myindex[startpos+4:startpos+4+mytestlen]:
				#found
				datapos=decodeint(myindex[startpos+4+mytestlen:startpos+8+mytestlen]);
				datalen=decodeint(myindex[startpos+8+mytestlen:startpos+12+mytestlen]);
				return datapos, datalen
		startpos=startpos+mytestlen+12
		
def getitem(myid,myitem):
	myindex=myid[0]
	mydata=myid[1]
	myloc=searchindex(myindex,myitem)
	if not myloc:
		return None
	return mydata[myloc[0]:myloc[0]+myloc[1]]

def xpand(myid,mydest):
	myindex=myid[0]
	mydata=myid[1]
	try:
		origdir=os.getcwd()
	except SystemExit, e:
		raise
	except:
		os.chdir("/")
		origdir="/"
	os.chdir(mydest)
	myindexlen=len(myindex)
	startpos=0
	while ((startpos+8)<myindexlen):
		namelen=decodeint(myindex[startpos:startpos+4])
		datapos=decodeint(myindex[startpos+4+namelen:startpos+8+namelen]);
		datalen=decodeint(myindex[startpos+8+namelen:startpos+12+namelen]);
		myname=myindex[startpos+4:startpos+4+namelen]
		dirname=os.path.dirname(myname)
		if dirname:
			if not os.path.exists(dirname):
				os.makedirs(dirname)
		mydat=open(myname,"w")
		mydat.write(mydata[datapos:datapos+datalen])
		mydat.close()
		startpos=startpos+namelen+12
	os.chdir(origdir)

class tbz2(object):
	def __init__(self,myfile):
		self.file=myfile
		self.filestat=None
		self.index=""
		self.infosize=0
		self.xpaksize=0
		self.indexsize=None
		self.datasize=None
		self.indexpos=None
		self.datapos=None
		self.scan()

	def decompose(self,datadir,cleanup=1):
		"""Alias for unpackinfo() --- Complement to recompose() but optionally
		deletes the destination directory. Extracts the xpak from the tbz2 into
		the directory provided. Raises IOError if scan() fails.
		Returns result of upackinfo()."""
		if not self.scan():
			raise IOError
		if cleanup:
			self.cleanup(datadir)
		if not os.path.exists(datadir):
			os.makedirs(datadir)
		return self.unpackinfo(datadir)
	def compose(self,datadir,cleanup=0):
		"""Alias for recompose()."""
		return self.recompose(datadir,cleanup)
	def recompose(self,datadir,cleanup=0):
		"""Creates an xpak segment from the datadir provided, truncates the tbz2
		to the end of regular data if an xpak segment already exists, and adds
		the new segment to the file with terminating info."""
		xpdata = xpak(datadir)
		self.recompose_mem(xpdata)
		if cleanup:
			self.cleanup(datadir)

	def recompose_mem(self, xpdata):
		self.scan() # Don't care about condition... We'll rewrite the data anyway.
		myfile=open(self.file,"a+")
		if not myfile:
			raise IOError
		myfile.seek(-self.xpaksize,2) # 0,2 or -0,2 just mean EOF.
		myfile.truncate()
		myfile.write(xpdata+encodeint(len(xpdata))+"STOP")
		myfile.flush()
		myfile.close()
		return 1

	def cleanup(self, datadir):
		datadir_split = os.path.split(datadir)
		if len(datadir_split) >= 2 and len(datadir_split[1]) > 0:
			# This is potentially dangerous,
			# thus the above sanity check.
			try:
				shutil.rmtree(datadir)
			except OSError, oe:
				if oe.errno == errno.ENOENT:
					pass
				else:
					raise oe

	def scan(self):
		"""Scans the tbz2 to locate the xpak segment and setup internal values.
		This function is called by relevant functions already."""
		try:
			mystat=os.stat(self.file)
			if self.filestat:
				changed=0
				for x in [ST_SIZE, ST_MTIME, ST_CTIME]:
					if mystat[x] != self.filestat[x]:
						changed=1
				if not changed:
					return 1
			self.filestat=mystat
			a=open(self.file,"r")
			a.seek(-16,2)
			trailer=a.read()
			self.infosize=0
			self.xpaksize=0
			if trailer[-4:]!="STOP":
				a.close()
				return 0
			if trailer[0:8]!="XPAKSTOP":
				a.close()
				return 0
			self.infosize=decodeint(trailer[8:12])
			self.xpaksize=self.infosize+8
			a.seek(-(self.xpaksize),2)
			header=a.read(16)
			if header[0:8]!="XPAKPACK":
				a.close()
				return 0
			self.indexsize=decodeint(header[8:12])
			self.datasize=decodeint(header[12:16])
			self.indexpos=a.tell()
			self.index=a.read(self.indexsize)
			self.datapos=a.tell()
			a.close()
			return 2
		except SystemExit, e:
			raise
		except:
			return 0

	def filelist(self):
		"""Return an array of each file listed in the index."""
		if not self.scan():
			return None
		return getindex_mem(self.index)

	def getfile(self,myfile,mydefault=None):
		"""Finds 'myfile' in the data segment and returns it."""
		if not self.scan():
			return None
		myresult=searchindex(self.index,myfile)
		if not myresult:
			return mydefault
		a=open(self.file,"r")
		a.seek(self.datapos+myresult[0],0)
		myreturn=a.read(myresult[1])
		a.close()
		return myreturn

	def getelements(self,myfile):
		"""A split/array representation of tbz2.getfile()"""
		mydat=self.getfile(myfile)
		if not mydat:
			return []
		return mydat.split()

	def unpackinfo(self,mydest):
		"""Unpacks all the files from the dataSegment into 'mydest'."""
		if not self.scan():
			return 0
		try:
			origdir=os.getcwd()
		except SystemExit, e:
			raise
		except:
			os.chdir("/")
			origdir="/"
		a=open(self.file,"r")
		if not os.path.exists(mydest):
			os.makedirs(mydest)
		os.chdir(mydest)
		startpos=0
		while ((startpos+8)<self.indexsize):
			namelen=decodeint(self.index[startpos:startpos+4])
			datapos=decodeint(self.index[startpos+4+namelen:startpos+8+namelen]);
			datalen=decodeint(self.index[startpos+8+namelen:startpos+12+namelen]);
			myname=self.index[startpos+4:startpos+4+namelen]
			dirname=os.path.dirname(myname)
			if dirname:
				if not os.path.exists(dirname):
					os.makedirs(dirname)
			mydat=open(myname,"w")
			a.seek(self.datapos+datapos)
			mydat.write(a.read(datalen))
			mydat.close()
			startpos=startpos+namelen+12
		a.close()
		os.chdir(origdir)
		return 1

	def get_data(self):
		"""Returns all the files from the dataSegment as a map object."""
		if not self.scan():
			return 0
		a = open(self.file, "r")
		mydata = {}
		startpos=0
		while ((startpos+8)<self.indexsize):
			namelen=decodeint(self.index[startpos:startpos+4])
			datapos=decodeint(self.index[startpos+4+namelen:startpos+8+namelen]);
			datalen=decodeint(self.index[startpos+8+namelen:startpos+12+namelen]);
			myname=self.index[startpos+4:startpos+4+namelen]
			a.seek(self.datapos+datapos)
			mydata[myname] = a.read(datalen)
			startpos=startpos+namelen+12
		a.close()
		return mydata

	def getboth(self):
		"""Returns an array [indexSegment,dataSegment]"""
		if not self.scan():
			return None

		a = open(self.file,"r")
		a.seek(self.datapos)
		mydata =a.read(self.datasize)
		a.close()

		return self.index, mydata

