// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
// $Id: tar.cc,v 1.4 2004/12/12 17:55:54 mdz Exp $
/* ######################################################################
Tar Inteface
##################################################################### */
/*}}}*/
// Include Files /*{{{*/
#include "generic.h"
#include
#include
#include
#include "apt_instmodule.h"
#include
/*}}}*/
class ProcessTar : public pkgDirStream
{
public:
PyObject *Function;
virtual bool DoItem(Item &Itm,int &Fd);
ProcessTar(PyObject *Function) : Function(Function)
{
Py_INCREF(Function);
}
virtual ~ProcessTar()
{
Py_DECREF(Function);
}
};
// ProcessTar::DoItem - Feed an item to a python function /*{{{*/
// ---------------------------------------------------------------------
/* The function is called with a tuple that has:
(FileName,Link,Mode,UID,GID,Size,MTime,Major,Minor) */
bool ProcessTar::DoItem(Item &Itm,int &Fd)
{
const char *Type;
switch (Itm.Type)
{
case Item::File:
Type = "FILE";
break;
case Item::HardLink:
Type = "HARDLINK";
break;
case Item::SymbolicLink:
Type = "SYMLINK";
break;
case Item::CharDevice:
Type = "CHARDEV";
break;
case Item::BlockDevice:
Type = "BLKDEV";
break;
case Item::Directory:
Type = "DIR";
break;
case Item::FIFO:
Type = "FIFO";
break;
}
if (PyObject_CallFunction(Function,"sssiiiiiii",Type,Itm.Name,
Itm.LinkTarget,Itm.Mode,Itm.UID,Itm.GID,Itm.Size,
Itm.MTime,Itm.Major,Itm.Minor) == 0)
return false;
Fd = -1;
return true;
}
/*}}}*/
// tarExtract - Examine files from a tar /*{{{*/
// ---------------------------------------------------------------------
/* */
char *doc_tarExtract =
"tarExtract(File,Func,Comp) -> None\n"
"The tar file referenced by the file object File, Func called for each\n"
"Tar member. Comp must be the string \"gzip\" (gzip is automatically invoked) \n";
PyObject *tarExtract(PyObject *Self,PyObject *Args)
{
PyObject *File;
PyObject *Function;
char *Comp;
if (PyArg_ParseTuple(Args,"O!Os",&PyFile_Type,&File,
&Function,&Comp) == 0)
return 0;
if (PyCallable_Check(Function) == 0)
{
PyErr_SetString(PyExc_TypeError,"argument 2: expected something callable.");
return 0;
}
{
// Open the file and associate the tar
FileFd Fd(fileno(PyFile_AsFile(File)),false);
ExtractTar Tar(Fd,0xFFFFFFFF,Comp);
if (_error->PendingError() == true)
return HandleErrors();
ProcessTar Proc(Function);
if (Tar.Go(Proc) == false)
return HandleErrors();
}
Py_INCREF(Py_None);
return HandleErrors(Py_None);
}
/*}}}*/
// debExtract - Examine files from a deb /*{{{*/
// ---------------------------------------------------------------------
/* */
char *doc_debExtract =
"debExtract(File,Func,Chunk) -> None\n"
"The deb referenced by the file object File is examined. The AR member\n"
"given by Chunk is treated as a tar.gz and fed through Func like\n"
"tarExtract\n";
PyObject *debExtract(PyObject *Self,PyObject *Args)
{
PyObject *File;
PyObject *Function;
char *Chunk;
const char *Comp = "gzip";
if (PyArg_ParseTuple(Args,"O!Os",&PyFile_Type,&File,
&Function,&Chunk) == 0)
return 0;
if (PyCallable_Check(Function) == 0)
{
PyErr_SetString(PyExc_TypeError,"argument 2: expected something callable.");
return 0;
}
{
// Open the file and associate the tar
// Open the file and associate the .deb
FileFd Fd(fileno(PyFile_AsFile(File)),false);
debDebFile Deb(Fd);
if (_error->PendingError() == true)
return HandleErrors();
// Get the archive member and positition the file
const ARArchive::Member *Member = Deb.GotoMember(Chunk);
if (Member == 0)
{
_error->Error("Cannot find chunk %s",Chunk);
return HandleErrors();
}
// Extract it.
if (strcmp(".bz2", &Chunk[strlen(Chunk)-4]) == 0)
Comp = "bzip2";
else if(strcmp(".lzma", &Chunk[strlen(Chunk)-5]) == 0)
Comp = "lzma";
ExtractTar Tar(Deb.GetFile(),Member->Size,Comp);
ProcessTar Proc(Function);
if (Tar.Go(Proc) == false)
return HandleErrors();
}
Py_INCREF(Py_None);
return HandleErrors(Py_None);
}
/*}}}*/