From: Arch Librarian Date: Mon, 20 Sep 2004 16:50:50 +0000 (+0000) Subject: Compile of apt-cache X-Git-Tag: 0.7.24ubuntu1~1707 X-Git-Url: https://git.saurik.com/apt.git/commitdiff_plain/1164783d22d97e7ca0454e23faad8f8bb70a901d Compile of apt-cache Author: jgg Date: 1998-07-15 05:56:42 GMT Compile of apt-cache --- diff --git a/Makefile b/Makefile index b2e55a57f..d28fd1350 100644 --- a/Makefile +++ b/Makefile @@ -8,4 +8,5 @@ all headers library clean veryclean binary program doc: $(MAKE) -C deity $@ $(MAKE) -C apt-pkg $@ + $(MAKE) -C cmdline $@ $(MAKE) -C doc $@ diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 1b087696d..6f515fd67 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: fileutl.cc,v 1.4 1998/07/12 23:58:48 jgg Exp $ +// $Id: fileutl.cc,v 1.5 1998/07/15 05:56:43 jgg Exp $ /* ###################################################################### File Utilities @@ -113,7 +113,7 @@ string SafeGetCWD() /* The most commonly used open mode combinations are given with Mode */ File::File(string FileName,OpenMode Mode, unsigned long Perms) { - Flags = 0; + Flags = AutoClose; switch (Mode) { case ReadOnly: @@ -205,9 +205,10 @@ bool File::Close() { bool Res = true; if ((Flags & AutoClose) == AutoClose) - if (close(iFd) != 0) + if (iFd >= 0 && close(iFd) != 0) Res &= _error->Errno("close","Problem closing the file"); - + iFd = -1; + if ((Flags & Fail) == Fail && (Flags & DelOnFail) == DelOnFail && FileName.empty() == false) if (unlink(FileName.c_str()) != 0) diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc index ccb706eab..22251c95a 100644 --- a/apt-pkg/contrib/mmap.cc +++ b/apt-pkg/contrib/mmap.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: mmap.cc,v 1.5 1998/07/12 23:58:50 jgg Exp $ +// $Id: mmap.cc,v 1.6 1998/07/15 05:56:44 jgg Exp $ /* ###################################################################### MMap Class - Provides 'real' mmap or a faked mmap using read(). @@ -80,12 +80,13 @@ bool MMap::Map() // MMap::Close - Close the map /*{{{*/ // --------------------------------------------------------------------- /* */ -bool MMap::Close(bool DoClose) +bool MMap::Close(bool DoClose, bool DoSync) { if (Fd.IsOpen() == false) return true; - Sync(); + if (DoSync == true) + Sync(); if (munmap((char *)Base,iSize) != 0) _error->Warning("Unable to munmap"); @@ -102,7 +103,7 @@ bool MMap::Close(bool DoClose) not return till all IO is complete */ bool MMap::Sync() { - if ((Flags & ReadOnly) == ReadOnly) + if ((Flags & ReadOnly) != ReadOnly) if (msync((char *)Base,iSize,MS_SYNC) != 0) return _error->Error("msync","Unable to write mmap"); return true; @@ -113,7 +114,7 @@ bool MMap::Sync() /* */ bool MMap::Sync(unsigned long Start,unsigned long Stop) { - if ((Flags & ReadOnly) == ReadOnly) + if ((Flags & ReadOnly) != ReadOnly) if (msync((char *)Base+(int)(Start/PAGE_SIZE)*PAGE_SIZE,Stop - Start,MS_SYNC) != 0) return _error->Error("msync","Unable to write mmap"); return true; @@ -140,7 +141,9 @@ DynamicMMap::DynamicMMap(File &F,unsigned long Flags,unsigned long WorkSpace) : DynamicMMap::~DynamicMMap() { unsigned long EndOfFile = iSize; - Close(false); + Sync(); + iSize = WorkSpace; + Close(false,false); ftruncate(Fd.Fd(),EndOfFile); Fd.Close(); } diff --git a/apt-pkg/contrib/mmap.h b/apt-pkg/contrib/mmap.h index 0e80c15d2..b935ac411 100644 --- a/apt-pkg/contrib/mmap.h +++ b/apt-pkg/contrib/mmap.h @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: mmap.h,v 1.4 1998/07/12 23:58:51 jgg Exp $ +// $Id: mmap.h,v 1.5 1998/07/15 05:56:45 jgg Exp $ /* ###################################################################### MMap Class - Provides 'real' mmap or a faked mmap using read(). @@ -43,7 +43,7 @@ class MMap void *Base; bool Map(); - bool Close(bool DoClose = true); + bool Close(bool DoClose = true,bool DoSync = true); public: diff --git a/buildlib/defaults.mak b/buildlib/defaults.mak index 05a4392a5..e5a63fc1b 100644 --- a/buildlib/defaults.mak +++ b/buildlib/defaults.mak @@ -55,6 +55,7 @@ DOC := $(BUILD)/doc LIBRARY_H = $(BASE)/buildlib/library.mak DEBIANDOC_H = $(BASE)/buildlib/debiandoc.mak MANPAGE_H = $(BASE)/buildlib/manpage.mak +PROGRAM_H = $(BASE)/buildlib/program.mak # Source location control # SUBDIRS specifies sub components of the module that @@ -70,7 +71,8 @@ HEADER_TARGETDIRS+= # Options include $(BUILD)/environment.mak -CPPFLAGS+= -I$(BUILD)/include +CPPFLAGS+= -I$(INCLUDE) +LDFLAGS+= -L$(LIB) # Phony rules. Other things hook these by appending to the dependency # list diff --git a/buildlib/program.mak b/buildlib/program.mak new file mode 100644 index 000000000..8bca3c24e --- /dev/null +++ b/buildlib/program.mak @@ -0,0 +1,47 @@ +# -*- make -*- + +# This creates a program + +# Input +# $(SOURCE) - The source code to use +# $(PROGRAM) - The name of the program +# $(SLIBS) - Shared libs to link against + +# See defaults.mak for information about LOCAL + +# Some local definitions +LOCAL := $(PROGRAM) +$(LOCAL)-OBJS := $(addprefix $(OBJ)/,$(addsuffix .o,$(notdir $(basename $(SOURCE))))) +$(LOCAL)-DEP := $(addprefix $(DEP)/,$(addsuffix .d,$(notdir $(basename $(SOURCE))))) +$(LOCAL)-BIN := $(BIN)/$(PROGRAM) +$(LOCAL)-SLIBS := $(SLIBS) + +# Install the command hooks +program: $(BIN)/$(PROGRAM) +clean: clean/$(LOCAL) +veryclean: veryclean/$(LOCAL) + +# The clean rules +.PHONY: clean/$(LOCAL) veryclean/$(LOCAL) +clean/$(LOCAL): + -rm -f $($(@F)-OBJS) $($(@F)-DEP) +veryclean/$(LOCAL): clean/$(LOCAL) + -rm -f $($(@F)-BIN) + +# The binary build rule +$($(LOCAL)-BIN): $($(LOCAL)-OBJS) + echo Building program $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(LFLAGS) -o $@ $(filter %.o,$^) $($(LOCAL)-SLIBS) + +# Compilation rules +vpath %.cc $(SUBDIRS) +$(OBJ)/%.o: %.cc + echo Compiling $< to $@ + $(CXX) -c $(INLINEDEPFLAG) $(CPPFLAGS) $(CXXFLAGS) -o $@ $< + $(DoDep) + +# Include the dependencies that are available +The_DFiles = $(wildcard $($(LOCAL)-DEP)) +ifneq ($(words $(The_DFiles)),0) +include $(The_DFiles) +endif diff --git a/cmdline/apt-cache.cc b/cmdline/apt-cache.cc new file mode 100644 index 000000000..ce7ccc2c9 --- /dev/null +++ b/cmdline/apt-cache.cc @@ -0,0 +1,386 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: apt-cache.cc,v 1.1 1998/07/15 05:56:47 jgg Exp $ +/* ###################################################################### + + apt-cache - Manages the cache file. + + This program should eventually handle both low and high level + manipulation of the cache file. Depending how far things go it + might get quite a sophisticated UI. + + Currently the command line is as follows: + apt-cache add cache file1:dist:ver file2:dist:ver ... + ie: + apt-cache add ./cache Pacakges:hamm:1.0 + + A usefull feature is 'upgradable' ie + apt-cache upgradable ./cache + will list .debs that should be installed to make all packages the latest + version. + + Returns 100 on failure, 0 on success. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include + +#include +#include + + /*}}}*/ + +string CacheFile; + +// SplitArg - Split the triple /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool SplitArg(const char *Arg,string &File,string &Dist,string Ver) +{ + const char *Start = Arg; + const char *I = Arg; + for (;*I != 0 && *I != ':'; I++); + if (*I != ':') + return _error->Error("Malformed argument %s, must be in file:dist:rev form",Arg); + File = string(Start,I - Start); + + I++; + Start = I; + for (;*I != 0 && *I != ':'; I++); + if (*I != ':') + return _error->Error("Malformed argument %s, must be in file:dist:rev form",Arg); + Dist = string(Start,I - Start); + + I++; + Start = I; + for (;*I != 0 && *I != ':'; I++); + if (I == Start) + return _error->Error("Malformed argument %s, must be in file:dist:rev form",Arg); + Ver = string(Start,I - Start); + + return true; +} + /*}}}*/ +// DoAdd - Perform an adding operation /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool DoAdd(int argc,char *argv[]) +{ + string FileName; + string Dist; + string Ver; + + File CacheF(CacheFile,File::WriteEmpty); + if (_error->PendingError() == true) + return false; + + DynamicMMap Map(CacheF,MMap::Public); + if (_error->PendingError() == true) + return false; + + pkgCacheGenerator Gen(Map); + if (_error->PendingError() == true) + return false; + + for (int I = 0; I != argc; I++) + { + if (SplitArg(argv[I],FileName,Dist,Ver) == false) + return false; + + // Do the merge + File TagF(FileName.c_str(),File::ReadOnly); + debListParser Parser(TagF); + if (_error->PendingError() == true) + return false; + if (Gen.SelectFile(FileName) == false) + return false; + + if (Gen.MergeList(Parser) == false) + return false; + } + + return true; +} + /*}}}*/ +// DumpPackage - Show a dump of a package record /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool DumpPackage(int argc,char *argv[]) +{ + File CacheF(CacheFile,File::ReadOnly); + if (_error->PendingError() == true) + return false; + + MMap Map(CacheF,MMap::Public | MMap::ReadOnly); + if (_error->PendingError() == true) + return false; + + pkgCache Cache(Map); + if (_error->PendingError() == true) + return false; + + for (int I = 0; I != argc; I++) + { + pkgCache::PkgIterator Pkg = Cache.FindPkg(argv[I]); + if (Pkg.end() == true) + { + _error->Warning("Unable to locate package %s",argv[0]); + continue; + } + + cout << "Package: " << Pkg.Name() << endl; + cout << "Versions: "; + for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++) + cout << Cur.VerStr() << ','; + cout << endl; + + cout << "Reverse Depends: " << endl; + for (pkgCache::DepIterator D = Pkg.RevDependsList(); D.end() != true; D++) + cout << " " << D.ParentPkg().Name() << ',' << D.TargetPkg().Name() << endl; + + cout << "Dependencies: " << endl; + for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++) + { + cout << Cur.VerStr() << " - "; + for (pkgCache::DepIterator Dep = Cur.DependsList(); Dep.end() != true; Dep++) + cout << Dep.TargetPkg().Name() << " (" << (int)Dep->CompareOp << " " << Dep.TargetVer() << ") "; + cout << endl; + } + + cout << "Provides: " << endl; + for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++) + { + cout << Cur.VerStr() << " - "; + for (pkgCache::PrvIterator Prv = Cur.ProvidesList(); Prv.end() != true; Prv++) + cout << Prv.ParentPkg().Name() << " "; + cout << endl; + } + } + + return true; +} + /*}}}*/ +// Stats - Dump some nice statistics /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool Stats(const char *FileName) +{ + File CacheF(FileName,File::ReadOnly); + if (_error->PendingError() == true) + return false; + + MMap Map(CacheF,MMap::Public | MMap::ReadOnly); + if (_error->PendingError() == true) + return false; + + pkgCache Cache(Map); + if (_error->PendingError() == true) + return false; + + cout << "Total Package Names : " << Cache.Head().PackageCount << endl; + pkgCache::PkgIterator I = Cache.PkgBegin(); + + int Normal = 0; + int Virtual = 0; + int NVirt = 0; + int DVirt = 0; + int Missing = 0; + for (;I.end() != true; I++) + { + if (I->VersionList != 0 && I->ProvidesList == 0) + { + Normal++; + continue; + } + + if (I->VersionList != 0 && I->ProvidesList != 0) + { + NVirt++; + continue; + } + + if (I->VersionList == 0 && I->ProvidesList != 0) + { + // Only 1 provides + if (I.ProvidesList()->NextProvides == 0) + { + DVirt++; + } + else + Virtual++; + continue; + } + if (I->VersionList == 0 && I->ProvidesList == 0) + { + Missing++; + continue; + } + } + cout << " Normal Packages: " << Normal << endl; + cout << " Pure Virtual Packages: " << Virtual << endl; + cout << " Single Virtual Packages: " << DVirt << endl; + cout << " Mixed Virtual Packages: " << NVirt << endl; + cout << " Missing: " << Missing << endl; + + cout << "Total Distinct Versions: " << Cache.Head().VersionCount << endl; + cout << "Total Dependencies: " << Cache.Head().DependsCount << endl; + return true; +} + /*}}}*/ +// Dump - show everything /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool Dump() +{ + File CacheF(CacheFile,File::ReadOnly); + if (_error->PendingError() == true) + return false; + + MMap Map(CacheF,MMap::Public | MMap::ReadOnly); + if (_error->PendingError() == true) + return false; + + pkgCache Cache(Map); + if (_error->PendingError() == true) + return false; + + for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++) + { + cout << "Package: " << P.Name() << endl; + for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++) + { + cout << " Version: " << V.VerStr() << endl; + cout << " File: " << V.FileList().File().FileName() << endl; + for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++) + cout << " Depends: " << D.TargetPkg().Name() << ' ' << D.TargetVer() << endl; + } + } + + for (pkgCache::PkgFileIterator F(Cache); F.end() == false; F++) + { + cout << "File: " << F.FileName() << endl; + cout << " Size: " << F->Size << endl; + cout << " ID: " << F->ID << endl; + cout << " Flags: " << F->Flags << endl; + cout << " Time: " << ctime(&F->mtime) << endl; + } + + return true; +} + /*}}}*/ +// DumpAvail - Print out the available list /*{{{*/ +// --------------------------------------------------------------------- +/* This is needed to make dpkg --merge happy */ +bool DumpAvail() +{ +#if 0 + pkgCache Cache(CacheFile,true,true); + if (_error->PendingError() == true) + return false; + + pkgControlCache CCache(Cache); + if (_error->PendingError() == true) + return false; + + vector Lines; + Lines.reserve(30); + + pkgCache::PkgIterator I = Cache.PkgBegin(); + for (;I.end() != true; I++) + { + if (I->VersionList == 0) + continue; + + pkgSPkgCtrlInfo Inf = CCache[I.VersionList()]; + if (Inf.isNull() == true) + return _error->Error("Couldn't locate info record"); + + // Iterate over each element + pkgPkgCtrlInfo::const_iterator Elm = Inf->begin(); + for (; Elm != Inf->end(); Elm++) + { + // Write the tag: value + cout << (*Elm)->Tag() << ": " << (*Elm)->Value() << endl; + + // Write the multiline + (*Elm)->GetLines(Lines); + for (vector::iterator j = Lines.begin(); j != Lines.end(); j++) + { + if ((*j).length() == 0) + cout << " ." << endl; + else + cout << " " << *j << endl; + } + + Lines.erase(Lines.begin(),Lines.end()); + } + + cout << endl; + } +#endif + return true; +} + /*}}}*/ + +int main(int argc, char *argv[]) +{ + // Check arguments. + if (argc < 3) + { + cerr << "Usage is apt-cache add cache file1:dist:ver file2:dist:ver ..." << endl; + return 100; + } + + while (1) + { + if (strcmp(argv[1],"add") == 0) + { + CacheFile = argv[2]; + if (DoAdd(argc - 3,argv + 3) == true) + Stats(argv[2]); + break; + } + + if (strcmp(argv[1],"showpkg") == 0) + { + CacheFile = argv[2]; + DumpPackage(argc - 3,argv + 3); + break; + } + + if (strcmp(argv[1],"stats") == 0) + { + Stats(argv[2]); + break; + } + + if (strcmp(argv[1],"dump") == 0) + { + CacheFile = argv[2]; + Dump(); + break; + } + + if (strcmp(argv[1],"dumpavail") == 0) + { + CacheFile = argv[2]; + DumpAvail(); + break; + } + + _error->Error("Invalid operation %s", argv[1]); + break; + } + + // Print any errors or warnings found during parsing + if (_error->empty() == false) + { + _error->DumpErrors(); + return 100; + } + + return 0; +} diff --git a/cmdline/makefile b/cmdline/makefile new file mode 100644 index 000000000..d521c58db --- /dev/null +++ b/cmdline/makefile @@ -0,0 +1,14 @@ +# -*- make -*- +BASE=.. + +# Bring in the default rules +include ../buildlib/defaults.mak + +# The library name +PROGRAM=apt-cache +SLIBS = -lapt-pkg + +# Source code for the contributed non-core things +SOURCE = apt-cache.cc + +include $(PROGRAM_H)