#include <config.h>
#include <unistd.h>
#include <fcntl.h>
#include <strings.h>
#include <kapp.h>

#include "tarprot.h"

TarProtocol::TarProtocol(const char *localFile, const char *file)
	:ArchiveProtocol(localFile,file)
{
	Type = Protocol::Tar;
	Code = 3;
	Prefix += "#tar:";
	int	f = ::open(localFile,O_RDONLY);
	uchar	buf[256];
	::read(f,buf,2);
	if (buf[0] == 31)
		if (buf[1] == 139) CompressProg = "gzip";
		else if (buf[1] == 157) CompressProg = "compress";
	::lseek(f,257,SEEK_SET);
	::read(f,buf,8);
	if (strncmp((char*)buf,"ustar",5) == 0) CompressProg = "none";
	::close(f);
	if (CompressProg.isEmpty() && LocalFile.right(3) == "bz2") CompressProg = "bzip2";
	ReadOnly = (CompressProg != "none");
cout << LocalFile << "\t" << CompressProg << endl;
}

TarProtocol::~TarProtocol()
{}

void TarProtocol::initCommand(QStrList& cmd)
{
	cmd.append("tar");
	if (!CompressProg.isEmpty() && CompressProg != "none") {
		QString		tmp("--use-compress-prog=");
		tmp += CompressProg;
		cmd.append(tmp.data());
	}
}

bool TarProtocol::thread_updateEntries()
{
	rawEntries->clear();
	DirDict->clear();
	TreeItem	*root = new TreeItem("/");
	DirDict->insert("/",root);
	QStrList	cmd;
	QString		str;
	int		status;
	initCommand(cmd);
	cmd.append("-tvf");
	cmd.append(LocalFile.data());
	if (!executeCommand("tar",cmd)) return FALSE;
	char	buf[2048], *last;
	while (1) {
		if (!fgets(buf,2048,fout)) break;
		strtok_r(buf,"\r\n",&last);
		FileInfo	*fi = new FileInfo(buf,Code);
		str = Prefix.data();
		str += fi->fileName();
		if (fi->isDir() && str[str.length()-1] != '/') str += '/';
		fi->setPath(str.data());
		processEntry(fi);
		rawEntries->append(fi);
	}
	finishCommand();
/*	FileInfoListIterator	it(*rawEntries);
	for (;it.current();++it) processEntry(it.current());*/
	if (WIFEXITED(status)) {
		updateFlag = FALSE;
		return TRUE;
	}
	updateFlag = TRUE;
	return FALSE;
}

void TarProtocol::createParentStr(QString& Str, FileInfo *fi)
{
	Str.truncate(0);
#define Date	fi->lastModified().date()
#define Time	fi->lastModified().time()
	Str.sprintf("%s %s/%s %d %.4d-%.2d-%.2d %.2d:%.2d ",fi->permissions().data(),fi->owner(),fi->group(),0,Date.year(),Date.month(),Date.day(),Time.hour(),Time.minute());
	Str[0] = 'd';
#undef 	Date
#undef	Time
}

bool TarProtocol::extract(const char *src, const char *dest, ProgressDlg *dlg)
{
	QStrList	cmd;
	initCommand(cmd);
	cmd.append("-C");
	cmd.append(dest);
	cmd.append("-xvf");
	cmd.append(LocalFile.data());
	cmd.append(src);
	if (!executeCommand("tar",cmd)) return FALSE;
	char	buf[2048], *last;
	while (1) {
		if (!fgets(buf,2048,fout)) break;
		strtok_r(buf,"\r\n",&last);
		if (dlg) {
			QString	msg(i18n("Extracting "));
			msg += buf;
			dlg->setLabelText(msg.data());
			dlg->setProgress(100);
		}
	}
	finishCommand();
	int	status;
	waitpid(ProcID,&status,0);
	if (WIFEXITED(status)) {
		updateFlag = FALSE;
		return TRUE;
	}
	return FALSE;
}
