Re: Bug#47379: [patch] local install
On Wed, Jan 28, 2004 at 11:46:39PM -0700, Jason Gunthorpe wrote:
>
> On Mon, 26 Jan 2004, Michael Vogt wrote:
>
> > We need a FileFd that contains the needed tags. In what way we obtain
> > the tags is irrelevant of course. I hope we find a better way than the
> > above for this :)
>
> You need to use the utils in apt-inst that provide raw .deb access in a
> way that is compatible with the tag record parser. Read the source to
> apt-ftparchive to find out how.. Though I'd rather not have apt-get linked
> with apt-utils :|
Thanks for this hints Jason. I attached another patch that does no
longer calls dpkg but uses debDebFile::MemControlExtract Extract("control")
instead.
The patch still has (at least) two problems:
1. It needs to link apt-pkg with apt-inst to get access to the debFile
class.
2. It creates a temporary file $pkgname.records in a insecure way.
The problem with 2) is that the temporary records file is needed in
debSinglePkgIndex::Merge() and debSPTypePkg::CreatePkgParser(). I
don't know how to pass additional information to CreatePkgParser() so
I used a predictable filename for now. This can be solved by creating
a temporary file in each of the two functions.
As for 1) I don't know what to do. We could use the dpkg fork/exec a
approach. Or we could copy-n-paste some code to extract only the
control file from a deb. All solutions are not optimal IMHO.
What do you think about this?
> Jason
Michael
--
Linux is not The Answer. Yes is the answer. Linux is The Question. - Neo
Index: apt-pkg/makefile
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/makefile,v
retrieving revision 1.38
diff -u -r1.38 makefile
--- apt-pkg/makefile 9 Feb 2003 22:02:45 -0000 1.38
+++ apt-pkg/makefile 19 Mar 2004 13:27:12 -0000
@@ -15,7 +15,7 @@
LIBEXT=$(GLIBC_VER)$(LIBSTDCPP_VER)
MAJOR=3.3
MINOR=0
-SLIBS=$(PTHREADLIB) $(INTLLIBS)
+SLIBS=$(PTHREADLIB) $(INTLLIBS) -lapt-inst
APT_DOMAIN:=libapt-pkg$(MAJOR)
# Source code for the contributed non-core things
Index: apt-pkg/pkgsystem.h
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/pkgsystem.h,v
retrieving revision 1.6
diff -u -r1.6 pkgsystem.h
--- apt-pkg/pkgsystem.h 11 Nov 2002 06:55:50 -0000 1.6
+++ apt-pkg/pkgsystem.h 19 Mar 2004 13:27:13 -0000
@@ -80,6 +80,7 @@
// Return a list of system index files..
virtual bool AddStatusFiles(std::vector<pkgIndexFile *> &List) = 0;
+ virtual bool AddSourceFiles(std::vector<pkgIndexFile *> &List) {};
virtual bool FindIndex(pkgCache::PkgFileIterator File,
pkgIndexFile *&Found) const = 0;
Index: apt-pkg/sourcelist.cc
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/sourcelist.cc,v
retrieving revision 1.24
diff -u -r1.24 sourcelist.cc
--- apt-pkg/sourcelist.cc 8 Jul 2002 04:18:07 -0000 1.24
+++ apt-pkg/sourcelist.cc 19 Mar 2004 13:27:14 -0000
@@ -18,6 +18,9 @@
#include <apt-pkg/configuration.h>
#include <apt-pkg/strutl.h>
+// CNC:2003-11-21
+#include <apt-pkg/pkgsystem.h>
+
#include <apti18n.h>
#include <fstream>
@@ -237,6 +240,8 @@
for (const_iterator I = SrcList.begin(); I != SrcList.end(); I++)
delete *I;
SrcList.erase(SrcList.begin(),SrcList.end());
+ // CNC:2003-11-21
+ _system->AddSourceFiles(SrcList);
char Buffer[300];
int CurLine = 0;
Index: apt-pkg/deb/debindexfile.cc
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/deb/debindexfile.cc,v
retrieving revision 1.6
diff -u -r1.6 debindexfile.cc
--- apt-pkg/deb/debindexfile.cc 4 Jan 2004 07:41:30 -0000 1.6
+++ apt-pkg/deb/debindexfile.cc 19 Mar 2004 13:27:18 -0000
@@ -23,8 +23,10 @@
#include <apt-pkg/error.h>
#include <apt-pkg/strutl.h>
#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/debfile.h>
#include <sys/stat.h>
+#include <stdio.h>
/*}}}*/
// SourcesIndex::debSourcesIndex - Constructor /*{{{*/
@@ -502,6 +504,176 @@
const pkgIndexFile::Type *debStatusIndex::GetType() const
{
return &_apt_Status;
+}
+
+// ---------------------------------------------------------
+
+class debSPTypePkg : public pkgIndexFile::Type
+{
+ public:
+
+ virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const
+ {
+ string FieldsFile = string(File.FileName()) + string(".records");
+ return new debRecordParser(FieldsFile, *File.Cache());
+ };
+ debSPTypePkg()
+ {
+ Label = "Debian Single File Package Index";
+ };
+};
+
+static debSPTypePkg _apt_Single_Pkg;
+
+debSinglePkgIndex::debSinglePkgIndex(string File)
+ : FilePath(File)
+{
+ // empty
+};
+
+bool debSinglePkgIndex::Merge(pkgCacheGenerator &Gen,OpProgress &Prog) const
+{
+ FileFd Fd(FilePath,FileFd::ReadOnly);
+ debDebFile Deb(Fd);
+
+ if(_error->PendingError() == true)
+ return false;
+
+ debDebFile::MemControlExtract Extract("control");
+ if (Extract.Read(Deb) == false) {
+ return false;
+ }
+
+ // write a temporary control file
+ string RecordsFile = string(FilePath+".records");
+ FILE *controlFile = fopen(RecordsFile.c_str(),"a");
+ struct stat S;
+ if(stat(FilePath.c_str(),&S) != 0)
+ _error->Error("Error stat() for %s ", FieldsFile.c_str());
+ fwrite(Extract.Control ,Extract.Length, 1 , controlFile);
+ fprintf(controlFile,"Size: %i\n",S.st_size);
+ fprintf(controlFile,"Filename: %s\n", FilePath.c_str());
+ fclose(controlFile);
+
+ // create file fd
+ FileFd Pkg(RecordsFile,FileFd::ReadOnly);
+ debListParser Parser(&Pkg);
+
+ Parser.setIsSingleFile(true);
+ Parser.setSingleFileName(FilePath);
+
+ if (_error->PendingError() == true)
+ return _error->Error("Problem opening %s",FilePath.c_str());
+
+ Prog.SubProgress(0,"mvo");
+ ::URI Tmp(URI);
+ //if (Gen.SelectFile(string(FilePath+".fields"),"host?",*this) == false)
+ if (Gen.SelectFile(FilePath,"host?",*this) == false)
+ return _error->Error("Problem with SelectFile %s",FilePath.c_str());
+
+ pkgCache::PkgFileIterator File = Gen.GetCurFile();
+ struct stat St;
+ if (stat(FilePath.c_str(),&St) != 0)
+ return _error->Errno("fstat","Failed to stat");
+ File->Size = St.st_size;
+ File->mtime = St.st_mtime;
+
+ if (Gen.MergeList(Parser) == false)
+ return _error->Error("Problem with MergeList %s", FilePath.c_str());
+
+ return true;
+};
+
+string debSinglePkgIndex::ArchiveURI(string File) const
+{
+ char *cwd = getcwd(NULL,0);
+ if (File[0] == '.' && File[1] == '/')
+ File = string(File, 2);
+ string URI = "file://"+flCombine(cwd, File);
+
+ return URI;
+}
+
+string debSinglePkgIndex::Describe(bool Short) const
+{
+ return FilePath;
+}
+
+bool debSinglePkgIndex::Exists() const
+{
+ return FileExists(FilePath);
+}
+bool debSinglePkgIndex::HasPackages() const
+{
+ return true;
+}
+unsigned long debSinglePkgIndex::Size() const
+{
+ struct stat St;
+ if(stat(FilePath.c_str(), &St) != 0) {
+ return 0;
+ }
+ return St.st_size;
+}
+
+const pkgIndexFile::Type *debSinglePkgIndex::GetType() const
+{
+ return &_apt_Single_Pkg;
+}
+
+string debSinglePkgIndex::MainType() const
+{
+ return "pkg";
+}
+
+string debSinglePkgIndex::IndexPath() const
+{
+ return FilePath;
+}
+
+bool debSinglePkgIndex::GetReleases(pkgAcquire *Owner) const
+{
+ return true;
+}
+
+
+bool debSinglePkgIndex::GetIndexes(pkgAcquire *Owner) const
+{
+ return true;
+}
+
+string debSinglePkgIndex::ArchiveInfo(pkgCache::VerIterator Ver) const
+{
+ return FilePath;
+}
+
+string debSinglePkgIndex::SourceInfo(pkgSrcRecords::Parser const &Record,
+ pkgSrcRecords::File const &File) const
+{
+ return string();
+}
+
+pkgCache::PkgFileIterator debSinglePkgIndex::FindInCache(pkgCache &Cache) const
+{
+ // stolen from rpmindexfile
+ string FileName = IndexPath();
+ pkgCache::PkgFileIterator File = Cache.FileBegin();
+ for (; File.end() == false; File++)
+ {
+ if (FileName != File.FileName())
+ continue;
+
+ struct stat St;
+ if (stat(File.FileName(),&St) != 0) {
+ return pkgCache::PkgFileIterator(Cache);
+ }
+ if ((unsigned)St.st_size != File->Size || St.st_mtime != File->mtime) {
+ return pkgCache::PkgFileIterator(Cache);
+ }
+ return File;
+ }
+
+ return File;
}
/*}}}*/
Index: apt-pkg/deb/debindexfile.h
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/deb/debindexfile.h,v
retrieving revision 1.3
diff -u -r1.3 debindexfile.h
--- apt-pkg/deb/debindexfile.h 29 Apr 2001 05:13:51 -0000 1.3
+++ apt-pkg/deb/debindexfile.h 19 Mar 2004 13:27:18 -0000
@@ -16,11 +16,49 @@
#ifndef PKGLIB_DEBINDEXFILE_H
#define PKGLIB_DEBINDEXFILE_H
+
#ifdef __GNUG__
#pragma interface "apt-pkg/debindexfile.h"
#endif
#include <apt-pkg/indexfile.h>
+#include <iostream>
+
+class debSinglePkgIndex : public pkgIndexFile
+{
+ protected:
+ string FilePath;
+ // this is the file with the package field information
+ string FieldsFile;
+
+ virtual string MainType() const;
+ virtual string IndexPath() const;
+
+ public:
+ virtual const Type *GetType() const;
+
+ virtual string ArchiveInfo(pkgCache::VerIterator Ver) const;
+ virtual string SourceInfo(pkgSrcRecords::Parser const &Record,
+ pkgSrcRecords::File const &File) const;
+
+ virtual bool GetReleases(pkgAcquire *Owner) const;
+ virtual bool GetIndexes(pkgAcquire *Owner) const;
+
+ virtual string ArchiveURI(string File) const;
+
+ virtual string Describe(bool Short = false) const;
+ virtual bool Exists() const;
+ virtual bool HasPackages() const;
+ virtual unsigned long Size() const;
+ virtual bool Merge(pkgCacheGenerator &/*Gen*/,OpProgress &/*Prog*/) const;
+ virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const;
+
+ debSinglePkgIndex(string File);
+
+};
+
+
+
class debStatusIndex : public pkgIndexFile
{
Index: apt-pkg/deb/deblistparser.cc
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/deb/deblistparser.cc,v
retrieving revision 1.29
diff -u -r1.29 deblistparser.cc
--- apt-pkg/deb/deblistparser.cc 22 Sep 2003 04:16:26 -0000 1.29
+++ apt-pkg/deb/deblistparser.cc 19 Mar 2004 13:27:21 -0000
@@ -31,7 +31,7 @@
// ListParser::debListParser - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
-debListParser::debListParser(FileFd *File) : Tags(File)
+debListParser::debListParser(FileFd *File) : Tags(File), isSingleFile(false)
{
Arch = _config->Find("APT::architecture");
}
@@ -47,6 +47,19 @@
return 0;
return WriteUniqString(Start,Stop - Start);
}
+
+void debListParser::setIsSingleFile(bool val)
+{
+ isSingleFile=val;
+};
+
+
+void debListParser::setSingleFileName(string s)
+{
+ SingleFileName=s;
+};
+
+
/*}}}*/
// ListParser::Package - Return the package name /*{{{*/
// ---------------------------------------------------------------------
@@ -113,7 +126,14 @@
if (ParseProvides(Ver) == false)
return false;
-
+
+ // mvo: we have a special case here for installing single local debs
+ if (isSingleFile) {
+ if(NewProvides(Ver, SingleFileName, "") == false) {
+ return false;
+ }
+ }
+
return true;
}
/*}}}*/
Index: apt-pkg/deb/deblistparser.h
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/deb/deblistparser.h,v
retrieving revision 1.9
diff -u -r1.9 deblistparser.h
--- apt-pkg/deb/deblistparser.h 20 Feb 2001 07:03:17 -0000 1.9
+++ apt-pkg/deb/deblistparser.h 19 Mar 2004 13:27:21 -0000
@@ -31,7 +31,10 @@
pkgTagSection Section;
unsigned long iOffset;
string Arch;
-
+
+ bool isSingleFile;
+ string SingleFileName;
+
unsigned long UniqFindTagWrite(const char *Tag);
bool ParseStatus(pkgCache::PkgIterator Pkg,pkgCache::VerIterator Ver);
bool ParseDepends(pkgCache::VerIterator Ver,const char *Tag,
@@ -40,6 +43,8 @@
static bool GrabWord(string Word,WordList *List,unsigned char &Out);
public:
+ void setIsSingleFile(bool val);
+ void setSingleFileName(string s);
static unsigned char GetPrio(string Str);
Index: apt-pkg/deb/debsystem.cc
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/deb/debsystem.cc,v
retrieving revision 1.4
diff -u -r1.4 debsystem.cc
--- apt-pkg/deb/debsystem.cc 26 Jan 2004 17:01:53 -0000 1.4
+++ apt-pkg/deb/debsystem.cc 19 Mar 2004 13:27:22 -0000
@@ -50,6 +50,26 @@
{
delete StatusFile;
}
+
+
+bool debSystem::AddSourceFiles(vector<pkgIndexFile *> &List)
+{
+ const Configuration::Item *Top;
+ Top = _config->Tree("APT::Arguments");
+ if (Top != 0)
+ {
+ for (Top = Top->Child; Top != 0; Top = Top->Next) {
+ const string &S = Top->Value;
+ if (FileExists(S) && flExtension(S) == "deb")
+ {
+ List.push_back(new debSinglePkgIndex(S));
+ }
+ }
+ }
+ return true;
+}
+
+
/*}}}*/
// System::Lock - Get the lock /*{{{*/
// ---------------------------------------------------------------------
Index: apt-pkg/deb/debsystem.h
===================================================================
RCS file: /cvs/deity/apt/apt-pkg/deb/debsystem.h,v
retrieving revision 1.4
diff -u -r1.4 debsystem.h
--- apt-pkg/deb/debsystem.h 11 Jan 2003 07:16:33 -0000 1.4
+++ apt-pkg/deb/debsystem.h 19 Mar 2004 13:27:22 -0000
@@ -35,6 +35,8 @@
virtual bool ArchiveSupported(const char *Type);
virtual signed Score(Configuration const &Cnf);
virtual bool AddStatusFiles(std::vector<pkgIndexFile *> &List);
+ //mvo
+ virtual bool AddSourceFiles(std::vector<pkgIndexFile *> &List);
virtual bool FindIndex(pkgCache::PkgFileIterator File,
pkgIndexFile *&Found) const;
Index: cmdline/apt-get.cc
===================================================================
RCS file: /cvs/deity/apt/cmdline/apt-get.cc,v
retrieving revision 1.155
diff -u -r1.155 apt-get.cc
--- cmdline/apt-get.cc 26 Feb 2004 19:17:55 -0000 1.155
+++ cmdline/apt-get.cc 19 Mar 2004 13:27:33 -0000
@@ -978,6 +978,41 @@
pkgCache::PkgIterator Tmp = Pkg.ProvidesList().OwnerPkg();
ioprintf(c1out,_("Note, selecting %s instead of %s\n"),
Tmp.Name(),Pkg.Name());
+ // CNC:2003-11-21 - Check if the current candidate is really
+ // providing that dependency
+ pkgCache::VerIterator Ver = Cache[Tmp].CandidateVerIter(Cache);
+ pkgCache::PrvIterator Prv = Ver.ProvidesList();
+ bool Found = false;
+
+ for (; Prv.end() == false; Prv++) {
+ if (strcmp(Prv.Name(), Pkg.Name()) == 0) {
+ Found = true;
+ break;
+ }
+ }
+ if (Found == false) {
+ // The current candidate doesn't provide the needed dependency.
+ // Look for one that does.
+ Ver = Tmp.VersionList();
+ for (; Ver.end() == false; Ver++) {
+ Prv = Ver.ProvidesList();
+ Found = false;
+ for (; Prv.end() == false; Prv++) {
+ if (strcmp(Prv.Name(), Pkg.Name()) == 0) {
+ Found = true;
+ break;
+ }
+ }
+ if (Found) {
+ Cache.SetCandidateVersion(Ver);
+ break;
+ }
+ }
+ if (Found == false) {
+ ioprintf(c1out,_("Internal error. Package %s doesn't provide %s\n"),Tmp.Name(),Pkg.Name());
+ return false;
+ }
+ }
Pkg = Tmp;
}
@@ -1374,7 +1409,7 @@
S[--Length] = 0;
continue;
}
-
+
char *Slash = strchr(S,'=');
if (Slash != 0)
{
@@ -2445,6 +2480,14 @@
_error->DumpErrors();
return 100;
+ }
+
+ // CNC:2003-11-21
+ if (CmdL.FileSize() != 1)
+ {
+ for (const char **I = CmdL.FileList + 1; *I != 0; I++) {
+ _config->Set("APT::Arguments::", *I);
+ }
}
// See if the help should be shown
Reply to: