summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/aptconfiguration.cc4
-rw-r--r--apt-pkg/cdrom.cc3
-rw-r--r--apt-pkg/contrib/cmndline.cc42
-rw-r--r--apt-pkg/contrib/cmndline.h1
-rw-r--r--apt-pkg/contrib/mmap.cc70
-rw-r--r--apt-pkg/contrib/mmap.h5
-rw-r--r--apt-pkg/contrib/strutl.cc12
-rw-r--r--apt-pkg/contrib/strutl.h1
-rw-r--r--apt-pkg/deb/debindexfile.cc12
-rw-r--r--apt-pkg/deb/debversion.cc18
-rw-r--r--apt-pkg/deb/dpkgpm.cc99
-rw-r--r--apt-pkg/deb/dpkgpm.h5
-rw-r--r--apt-pkg/depcache.cc24
-rw-r--r--apt-pkg/depcache.h2
-rw-r--r--apt-pkg/init.cc1
-rw-r--r--apt-pkg/init.h2
-rw-r--r--apt-pkg/pkgcachegen.cc28
-rw-r--r--apt-pkg/tagfile.cc13
-rw-r--r--apt-pkg/tagfile.h15
19 files changed, 283 insertions, 74 deletions
diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc
index 429219cbd..a1379ce7d 100644
--- a/apt-pkg/aptconfiguration.cc
+++ b/apt-pkg/aptconfiguration.cc
@@ -152,6 +152,7 @@ std::vector<std::string> const Configuration::getLanguages(bool const &All,
builtin.push_back(c);
}
}
+ closedir(D);
// get the environment language codes: LC_MESSAGES (and later LANGUAGE)
// we extract both, a long and a short code and then we will
@@ -217,7 +218,8 @@ std::vector<std::string> const Configuration::getLanguages(bool const &All,
environment.push_back(envLong);
environment.push_back(envShort);
// take care of LANGUAGE
- string envLang = Locale == 0 ? getenv("LANGUAGE") : *(Locale+1);
+ const char *language_env = getenv("LANGUAGE") == 0 ? "" : getenv("LANGUAGE");
+ string envLang = Locale == 0 ? language_env : *(Locale+1);
if (envLang.empty() == false) {
std::vector<string> env = ExplodeString(envLang,':');
short addedLangs = 0; // add a maximum of 3 fallbacks from the environment
diff --git a/apt-pkg/cdrom.cc b/apt-pkg/cdrom.cc
index 83165c6c0..93deb49c4 100644
--- a/apt-pkg/cdrom.cc
+++ b/apt-pkg/cdrom.cc
@@ -281,7 +281,8 @@ bool pkgCdrom::DropRepeats(vector<string> &List,const char *Name)
List[J] = string();
}
}
-
+ delete[] Inodes;
+
// Wipe erased entries
for (unsigned int I = 0; I < List.size();)
{
diff --git a/apt-pkg/contrib/cmndline.cc b/apt-pkg/contrib/cmndline.cc
index bfd53695e..0b16bf51a 100644
--- a/apt-pkg/contrib/cmndline.cc
+++ b/apt-pkg/contrib/cmndline.cc
@@ -135,7 +135,9 @@ bool CommandLine::Parse(int argc,const char **argv)
for (; I != argc; I++)
*Files++ = argv[I];
*Files = 0;
-
+
+ SaveInConfig(argc, argv);
+
return true;
}
/*}}}*/
@@ -351,3 +353,41 @@ bool CommandLine::DispatchArg(Dispatch *Map,bool NoMatch)
return false;
}
/*}}}*/
+// CommandLine::SaveInConfig - for output later in a logfile or so /*{{{*/
+// ---------------------------------------------------------------------
+/* We save the commandline here to have it around later for e.g. logging.
+ It feels a bit like a hack here and isn't bulletproof, but it is better
+ than nothing after all. */
+void CommandLine::SaveInConfig(unsigned int const &argc, char const * const * const argv)
+{
+ char cmdline[300];
+ unsigned int length = 0;
+ bool lastWasOption = false;
+ bool closeQuote = false;
+ for (unsigned int i = 0; i < argc; ++i, ++length)
+ {
+ for (unsigned int j = 0; argv[i][j] != '\0' && length < sizeof(cmdline)-1; ++j, ++length)
+ {
+ cmdline[length] = argv[i][j];
+ if (lastWasOption == true && argv[i][j] == '=')
+ {
+ // That is possibly an option: Quote it if it includes spaces,
+ // the benefit is that this will eliminate also most false positives
+ const char* c = &argv[i][j+1];
+ for (; *c != '\0' && *c != ' '; ++c);
+ if (*c == '\0') continue;
+ cmdline[++length] = '"';
+ closeQuote = true;
+ }
+ }
+ if (closeQuote == true)
+ cmdline[length++] = '"';
+ // Problem: detects also --hello
+ if (cmdline[length-1] == 'o')
+ lastWasOption = true;
+ cmdline[length] = ' ';
+ }
+ cmdline[--length] = '\0';
+ _config->Set("CommandLine::AsString", cmdline);
+}
+ /*}}}*/
diff --git a/apt-pkg/contrib/cmndline.h b/apt-pkg/contrib/cmndline.h
index e28071e81..7c0c71aa7 100644
--- a/apt-pkg/contrib/cmndline.h
+++ b/apt-pkg/contrib/cmndline.h
@@ -60,6 +60,7 @@ class CommandLine
Configuration *Conf;
bool HandleOpt(int &I,int argc,const char *argv[],
const char *&Opt,Args *A,bool PreceedeMatch = false);
+ void static SaveInConfig(unsigned int const &argc, char const * const * const argv);
public:
diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc
index f440f9489..b3f29032c 100644
--- a/apt-pkg/contrib/mmap.cc
+++ b/apt-pkg/contrib/mmap.cc
@@ -27,6 +27,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
+#include <errno.h>
#include <cstring>
/*}}}*/
@@ -35,7 +36,7 @@
// ---------------------------------------------------------------------
/* */
MMap::MMap(FileFd &F,unsigned long Flags) : Flags(Flags), iSize(0),
- Base(0)
+ Base(0), SyncToFd(NULL)
{
if ((Flags & NoImmMap) != NoImmMap)
Map(F);
@@ -45,7 +46,7 @@ MMap::MMap(FileFd &F,unsigned long Flags) : Flags(Flags), iSize(0),
// ---------------------------------------------------------------------
/* */
MMap::MMap(unsigned long Flags) : Flags(Flags), iSize(0),
- Base(0)
+ Base(0), SyncToFd(NULL)
{
}
/*}}}*/
@@ -78,7 +79,24 @@ bool MMap::Map(FileFd &Fd)
// Map it.
Base = mmap(0,iSize,Prot,Map,Fd.Fd(),0);
if (Base == (void *)-1)
- return _error->Errno("mmap",_("Couldn't make mmap of %lu bytes"),iSize);
+ {
+ if (errno == ENODEV || errno == EINVAL)
+ {
+ // The filesystem doesn't support this particular kind of mmap.
+ // So we allocate a buffer and read the whole file into it.
+ int const dupped_fd = dup(Fd.Fd());
+ if (dupped_fd == -1)
+ return _error->Errno("mmap", _("Couldn't duplicate file descriptor %i"), Fd.Fd());
+
+ Base = new unsigned char[iSize];
+ SyncToFd = new FileFd (dupped_fd);
+ if (!SyncToFd->Seek(0L) || !SyncToFd->Read(Base, iSize))
+ return false;
+ }
+ else
+ return _error->Errno("mmap",_("Couldn't make mmap of %lu bytes"),
+ iSize);
+ }
return true;
}
@@ -93,10 +111,19 @@ bool MMap::Close(bool DoSync)
if (DoSync == true)
Sync();
-
- if (munmap((char *)Base,iSize) != 0)
- _error->Warning("Unable to munmap");
-
+
+ if (SyncToFd != NULL)
+ {
+ delete[] (char *)Base;
+ delete SyncToFd;
+ SyncToFd = NULL;
+ }
+ else
+ {
+ if (munmap((char *)Base, iSize) != 0)
+ _error->WarningE("mmap", _("Unable to close mmap"));
+ }
+
iSize = 0;
Base = 0;
return true;
@@ -113,8 +140,18 @@ bool MMap::Sync()
#ifdef _POSIX_SYNCHRONIZED_IO
if ((Flags & ReadOnly) != ReadOnly)
- if (msync((char *)Base,iSize,MS_SYNC) < 0)
- return _error->Errno("msync","Unable to write mmap");
+ {
+ if (SyncToFd != NULL)
+ {
+ if (!SyncToFd->Seek(0) || !SyncToFd->Write(Base, iSize))
+ return false;
+ }
+ else
+ {
+ if (msync((char *)Base, iSize, MS_SYNC) < 0)
+ return _error->Errno("msync", _("Unable to synchronize mmap"));
+ }
+ }
#endif
return true;
}
@@ -130,8 +167,19 @@ bool MMap::Sync(unsigned long Start,unsigned long Stop)
#ifdef _POSIX_SYNCHRONIZED_IO
unsigned long PSize = sysconf(_SC_PAGESIZE);
if ((Flags & ReadOnly) != ReadOnly)
- if (msync((char *)Base+(int)(Start/PSize)*PSize,Stop - Start,MS_SYNC) < 0)
- return _error->Errno("msync","Unable to write mmap");
+ {
+ if (SyncToFd != 0)
+ {
+ if (!SyncToFd->Seek(0) ||
+ !SyncToFd->Write (((char *)Base)+Start, Stop-Start))
+ return false;
+ }
+ else
+ {
+ if (msync((char *)Base+(int)(Start/PSize)*PSize,Stop - Start,MS_SYNC) < 0)
+ return _error->Errno("msync", _("Unable to synchronize mmap"));
+ }
+ }
#endif
return true;
}
diff --git a/apt-pkg/contrib/mmap.h b/apt-pkg/contrib/mmap.h
index cd2b15ba2..5ca951204 100644
--- a/apt-pkg/contrib/mmap.h
+++ b/apt-pkg/contrib/mmap.h
@@ -44,6 +44,11 @@ class MMap
unsigned long iSize;
void *Base;
+ // In case mmap can not be used, we keep a dup of the file
+ // descriptor that should have been mmaped so that we can write to
+ // the file in Sync().
+ FileFd *SyncToFd;
+
bool Map(FileFd &Fd);
bool Close(bool DoSync = true);
diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc
index 3bbaf5f30..1b9922a31 100644
--- a/apt-pkg/contrib/strutl.cc
+++ b/apt-pkg/contrib/strutl.cc
@@ -1341,3 +1341,15 @@ string URI::SiteOnly(const string &URI)
return U;
}
/*}}}*/
+// URI::NoUserPassword - Return the schema, site and path for the URI /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+string URI::NoUserPassword(const string &URI)
+{
+ ::URI U(URI);
+ U.User.clear();
+ U.Password.clear();
+ U.Port = 0;
+ return U;
+}
+ /*}}}*/
diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h
index d65f975d2..e72288f4c 100644
--- a/apt-pkg/contrib/strutl.h
+++ b/apt-pkg/contrib/strutl.h
@@ -121,6 +121,7 @@ class URI
inline void operator =(const string &From) {CopyFrom(From);};
inline bool empty() {return Access.empty();};
static string SiteOnly(const string &URI);
+ static string NoUserPassword(const string &URI);
URI(string Path) {CopyFrom(Path);};
URI() : Port(0) {};
diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc
index bb8fae7cb..b89429d86 100644
--- a/apt-pkg/deb/debindexfile.cc
+++ b/apt-pkg/deb/debindexfile.cc
@@ -35,12 +35,12 @@ debSourcesIndex::debSourcesIndex(string URI,string Dist,string Section,bool Trus
// SourcesIndex::SourceInfo - Short 1 liner describing a source /*{{{*/
// ---------------------------------------------------------------------
/* The result looks like:
- http://foo/ stable/main src 1.1.1 (dsc) */
+ http://foo/debian/ stable/main src 1.1.1 (dsc) */
string debSourcesIndex::SourceInfo(pkgSrcRecords::Parser const &Record,
pkgSrcRecords::File const &File) const
{
string Res;
- Res = ::URI::SiteOnly(URI) + ' ';
+ Res = ::URI::NoUserPassword(URI) + ' ';
if (Dist[Dist.size() - 1] == '/')
{
if (Dist != "/")
@@ -88,7 +88,7 @@ string debSourcesIndex::Describe(bool Short) const
/* */
string debSourcesIndex::Info(const char *Type) const
{
- string Info = ::URI::SiteOnly(URI) + ' ';
+ string Info = ::URI::NoUserPassword(URI) + ' ';
if (Dist[Dist.size() - 1] == '/')
{
if (Dist != "/")
@@ -162,7 +162,7 @@ debPackagesIndex::debPackagesIndex(string const &URI, string const &Dist, string
/* This is a shorter version that is designed to be < 60 chars or so */
string debPackagesIndex::ArchiveInfo(pkgCache::VerIterator Ver) const
{
- string Res = ::URI::SiteOnly(URI) + ' ';
+ string Res = ::URI::NoUserPassword(URI) + ' ';
if (Dist[Dist.size() - 1] == '/')
{
if (Dist != "/")
@@ -200,7 +200,7 @@ string debPackagesIndex::Describe(bool Short) const
/* */
string debPackagesIndex::Info(const char *Type) const
{
- string Info = ::URI::SiteOnly(URI) + ' ';
+ string Info = ::URI::NoUserPassword(URI) + ' ';
if (Dist[Dist.size() - 1] == '/')
{
if (Dist != "/")
@@ -402,7 +402,7 @@ string debTranslationsIndex::Describe(bool Short) const
/* */
string debTranslationsIndex::Info(const char *Type) const
{
- string Info = ::URI::SiteOnly(URI) + ' ';
+ string Info = ::URI::NoUserPassword(URI) + ' ';
if (Dist[Dist.size() - 1] == '/')
{
if (Dist != "/")
diff --git a/apt-pkg/deb/debversion.cc b/apt-pkg/deb/debversion.cc
index ad45e9a44..755ffbe96 100644
--- a/apt-pkg/deb/debversion.cc
+++ b/apt-pkg/deb/debversion.cc
@@ -190,8 +190,22 @@ int debVersioningSystem::DoCmpVersion(const char *A,const char *AEnd,
dlhs++;
if (drhs != rhs)
drhs++;
-
- return CmpFragment(dlhs,AEnd,drhs,BEnd);
+
+ // no debian revision need to be treated like -0
+ if (*(dlhs-1) == '-' && *(drhs-1) == '-')
+ return CmpFragment(dlhs,AEnd,drhs,BEnd);
+ else if (*(dlhs-1) == '-')
+ {
+ const char* null = "0";
+ return CmpFragment(dlhs,AEnd,null, null+1);
+ }
+ else if (*(drhs-1) == '-')
+ {
+ const char* null = "0";
+ return CmpFragment(null, null+1, drhs, BEnd);
+ }
+ else
+ return 0;
}
/*}}}*/
// debVS::CheckDep - Check a single dependency /*{{{*/
diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc
index 3dca2b209..9ba60060c 100644
--- a/apt-pkg/deb/dpkgpm.cc
+++ b/apt-pkg/deb/dpkgpm.cc
@@ -550,46 +550,108 @@ void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd)
dpkgbuf_pos = dpkgbuf+dpkgbuf_pos-p;
}
/*}}}*/
+// DPkgPM::WriteHistoryTag /*{{{*/
+void pkgDPkgPM::WriteHistoryTag(string tag, string value)
+{
+ if (value.size() > 0)
+ {
+ // poor mans rstrip(", ")
+ if (value[value.size()-2] == ',' && value[value.size()-1] == ' ')
+ value.erase(value.size() - 2, 2);
+ fprintf(history_out, "%s: %s\n", tag.c_str(), value.c_str());
+ }
+} /*}}}*/
// DPkgPM::OpenLog /*{{{*/
bool pkgDPkgPM::OpenLog()
{
- string logdir = _config->FindDir("Dir::Log");
+ string const logdir = _config->FindDir("Dir::Log");
if(not FileExists(logdir))
return _error->Error(_("Directory '%s' missing"), logdir.c_str());
- string logfile_name = flCombine(logdir,
+
+ // get current time
+ char timestr[200];
+ time_t const t = time(NULL);
+ struct tm const * const tmp = localtime(&t);
+ strftime(timestr, sizeof(timestr), "%F %T", tmp);
+
+ // open terminal log
+ string const logfile_name = flCombine(logdir,
_config->Find("Dir::Log::Terminal"));
if (!logfile_name.empty())
{
term_out = fopen(logfile_name.c_str(),"a");
if (term_out == NULL)
- return _error->WarningE(_("Could not open file '%s'"), logfile_name.c_str());
+ return _error->WarningE("OpenLog", _("Could not open file '%s'"), logfile_name.c_str());
chmod(logfile_name.c_str(), 0600);
- // output current time
- char outstr[200];
- time_t t = time(NULL);
- struct tm *tmp = localtime(&t);
- strftime(outstr, sizeof(outstr), "%F %T", tmp);
- fprintf(term_out, "\nLog started: %s\n", outstr);
+ fprintf(term_out, "\nLog started: %s\n", timestr);
}
+
+ // write your history
+ string const history_name = flCombine(logdir,
+ _config->Find("Dir::Log::History"));
+ if (!history_name.empty())
+ {
+ history_out = fopen(history_name.c_str(),"a");
+ if (history_out == NULL)
+ return _error->WarningE("OpenLog", _("Could not open file '%s'"), history_name.c_str());
+ chmod(history_name.c_str(), 0644);
+ fprintf(history_out, "\nStart-Date: %s\n", timestr);
+ string remove, purge, install, upgrade, downgrade;
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
+ {
+ if (Cache[I].NewInstall())
+ install += I.Name() + string(" (") + Cache[I].CandVersion + string("), ");
+ else if (Cache[I].Upgrade())
+ upgrade += I.Name() + string(" (") + Cache[I].CurVersion + string(", ") + Cache[I].CandVersion + string("), ");
+ else if (Cache[I].Downgrade())
+ downgrade += I.Name() + string(" (") + Cache[I].CurVersion + string(", ") + Cache[I].CandVersion + string("), ");
+ else if (Cache[I].Delete())
+ {
+ if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge)
+ purge += I.Name() + string(" (") + Cache[I].CurVersion + string("), ");
+ else
+ remove += I.Name() + string(" (") + Cache[I].CurVersion + string("), ");
+ }
+ }
+ if (_config->Exists("Commandline::AsString") == true)
+ WriteHistoryTag("Commandline", _config->Find("Commandline::AsString"));
+ WriteHistoryTag("Install", install);
+ WriteHistoryTag("Upgrade", upgrade);
+ WriteHistoryTag("Downgrade",downgrade);
+ WriteHistoryTag("Remove",remove);
+ WriteHistoryTag("Purge",purge);
+ fflush(history_out);
+ }
+
return true;
}
/*}}}*/
// DPkg::CloseLog /*{{{*/
bool pkgDPkgPM::CloseLog()
{
+ char timestr[200];
+ time_t t = time(NULL);
+ struct tm *tmp = localtime(&t);
+ strftime(timestr, sizeof(timestr), "%F %T", tmp);
+
if(term_out)
{
- char outstr[200];
- time_t t = time(NULL);
- struct tm *tmp = localtime(&t);
- strftime(outstr, sizeof(outstr), "%F %T", tmp);
fprintf(term_out, "Log ended: ");
- fprintf(term_out, "%s", outstr);
+ fprintf(term_out, "%s", timestr);
fprintf(term_out, "\n");
fclose(term_out);
}
term_out = NULL;
+
+ if(history_out)
+ {
+ if (dpkg_error.size() > 0)
+ fprintf(history_out, "Error: %s\n", dpkg_error.c_str());
+ fprintf(history_out, "End-Date: %s\n", timestr);
+ fclose(history_out);
+ }
+
return true;
}
/*}}}*/
@@ -1059,11 +1121,14 @@ bool pkgDPkgPM::Go(int OutStatusFd)
RunScripts("DPkg::Post-Invoke");
if (WIFSIGNALED(Status) != 0 && WTERMSIG(Status) == SIGSEGV)
- _error->Error("Sub-process %s received a segmentation fault.",Args[0]);
+ strprintf(dpkg_error, "Sub-process %s received a segmentation fault.",Args[0]);
else if (WIFEXITED(Status) != 0)
- _error->Error("Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status));
+ strprintf(dpkg_error, "Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status));
else
- _error->Error("Sub-process %s exited unexpectedly",Args[0]);
+ strprintf(dpkg_error, "Sub-process %s exited unexpectedly",Args[0]);
+
+ if(dpkg_error.size() > 0)
+ _error->Error(dpkg_error.c_str());
if(stopOnError)
{
diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h
index 43e5c7d45..330c788a2 100644
--- a/apt-pkg/deb/dpkgpm.h
+++ b/apt-pkg/deb/dpkgpm.h
@@ -29,7 +29,9 @@ class pkgDPkgPM : public pkgPackageManager
char dpkgbuf[1024];
int dpkgbuf_pos;
FILE *term_out;
-
+ FILE *history_out;
+ string dpkg_error;
+
protected:
// progress reporting
@@ -66,6 +68,7 @@ class pkgDPkgPM : public pkgPackageManager
// Helpers
bool RunScriptsWithPkgs(const char *Cnf);
bool SendV2Pkgs(FILE *F);
+ void WriteHistoryTag(string tag, string value);
// dpkg log
bool OpenLog();
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index ffa4fe71c..75f69ee11 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -257,7 +257,22 @@ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly) /*{{{*/
pkgCache::PkgIterator pkg = Cache->FindPkg(pkgname, pkgarch);
if(pkg.end() || pkg.VersionList().end())
continue;
- bool const newAuto = (PkgState[pkg->ID].Flags & Flag::Auto);
+ StateCache const &P = PkgState[pkg->ID];
+ bool newAuto = (P.Flags & Flag::Auto);
+ // skip not installed or now-removed ones if requested
+ if (InstalledOnly && (
+ (pkg->CurrentVer == 0 && P.Mode != ModeInstall) ||
+ (pkg->CurrentVer != 0 && P.Mode == ModeDelete)))
+ {
+ // The section is obsolete if it contains no other tag
+ unsigned int const count = section.Count();
+ if (count < 2 ||
+ (count == 2 && section.Exists("Auto-Installed")) ||
+ (count == 3 && section.Exists("Auto-Installed") && section.Exists("Architecture")))
+ continue;
+ else
+ newAuto = false;
+ }
if(_config->FindB("Debug::pkgAutoRemove",false))
std::clog << "Update existing AutoInstall info: "
<< pkg.FullName() << std::endl;
@@ -277,14 +292,17 @@ bool pkgDepCache::writeStateFile(OpProgress *prog, bool InstalledOnly) /*{{{*/
// then write the ones we have not seen yet
std::ostringstream ostr;
for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end(); pkg++) {
- if(PkgState[pkg->ID].Flags & Flag::Auto) {
+ StateCache const &P = PkgState[pkg->ID];
+ if(P.Flags & Flag::Auto) {
if (pkgs_seen.find(pkg.FullName()) != pkgs_seen.end()) {
if(debug_autoremove)
std::clog << "Skipping already written " << pkg.FullName() << std::endl;
continue;
}
// skip not installed ones if requested
- if(InstalledOnly && pkg->CurrentVer == 0)
+ if (InstalledOnly && (
+ (pkg->CurrentVer == 0 && P.Mode != ModeInstall) ||
+ (pkg->CurrentVer != 0 && P.Mode == ModeDelete)))
continue;
const char* const pkgarch = pkg.Arch();
if (strcmp(pkgarch, "all") == 0)
diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h
index ea605f199..6765d3e7c 100644
--- a/apt-pkg/depcache.h
+++ b/apt-pkg/depcache.h
@@ -447,7 +447,7 @@ class pkgDepCache : protected pkgCache::Namespace
// read persistent states
bool readStateFile(OpProgress *prog);
- bool writeStateFile(OpProgress *prog, bool InstalledOnly=false);
+ bool writeStateFile(OpProgress *prog, bool InstalledOnly=true);
// Size queries
inline double UsrSize() {return iUsrSize;};
diff --git a/apt-pkg/init.cc b/apt-pkg/init.cc
index d8c201b9d..6310aff11 100644
--- a/apt-pkg/init.cc
+++ b/apt-pkg/init.cc
@@ -75,6 +75,7 @@ bool pkgInitConfig(Configuration &Cnf)
// State
Cnf.Set("Dir::Log","var/log/apt");
Cnf.Set("Dir::Log::Terminal","term.log");
+ Cnf.Set("Dir::Log::History","history.log");
// Translation
Cnf.Set("APT::Acquire::Translation", "environment");
diff --git a/apt-pkg/init.h b/apt-pkg/init.h
index f0757f644..b3e4b147f 100644
--- a/apt-pkg/init.h
+++ b/apt-pkg/init.h
@@ -22,7 +22,7 @@
// Non-ABI-Breaks should only increase RELEASE number.
// See also buildlib/libversion.mak
#define APT_PKG_MAJOR 4
-#define APT_PKG_MINOR 8
+#define APT_PKG_MINOR 9
#define APT_PKG_RELEASE 0
extern const char *pkgVersion;
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
index 3d1a654d1..8187b3950 100644
--- a/apt-pkg/pkgcachegen.cc
+++ b/apt-pkg/pkgcachegen.cc
@@ -189,17 +189,22 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
pkgCache::VerIterator Ver = Pkg.VersionList();
map_ptrloc *LastVer = &Pkg->VersionList;
int Res = 1;
+ unsigned long const Hash = List.VersionHash();
for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++)
{
Res = Cache.VS->CmpVersion(Version,Ver.VerStr());
- if (Res >= 0)
+ // Version is higher as current version - insert here
+ if (Res > 0)
break;
+ // Versionstrings are equal - is hash also equal?
+ if (Res == 0 && Ver->Hash == Hash)
+ break;
+ // proceed with the next till we have either the right
+ // or we found another version (which will be lower)
}
-
- /* We already have a version for this item, record that we
- saw it */
- unsigned long Hash = List.VersionHash();
- if (Res == 0 && Ver->Hash == Hash)
+
+ /* We already have a version for this item, record that we saw it */
+ if (Res == 0 && Ver.end() == false && Ver->Hash == Hash)
{
if (List.UsePackage(Pkg,Ver) == false)
return _error->Error(_("Error occurred while processing %s (UsePackage2)"),
@@ -218,17 +223,6 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
}
continue;
- }
-
- // Skip to the end of the same version set.
- if (Res == 0)
- {
- for (; Ver.end() == false; LastVer = &Ver->NextVer, Ver++)
- {
- Res = Cache.VS->CmpVersion(Version,Ver.VerStr());
- if (Res != 0)
- break;
- }
}
// Add a new version
diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc
index 7c5d15a58..0d4999ee7 100644
--- a/apt-pkg/tagfile.cc
+++ b/apt-pkg/tagfile.cc
@@ -193,17 +193,8 @@ bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long Offset)
/*}}}*/
// TagSection::Scan - Scan for the end of the header information /*{{{*/
// ---------------------------------------------------------------------
-/* This looks for the first double new line in the data stream. It also
- indexes the tags in the section. This very simple hash function for the
- last 8 letters gives very good performance on the debian package files */
-inline static unsigned long AlphaHash(const char *Text, const char *End = 0)
-{
- unsigned long Res = 0;
- for (; Text != End && *Text != ':' && *Text != 0; Text++)
- Res = ((unsigned long)(*Text) & 0xDF) ^ (Res << 1);
- return Res & 0xFF;
-}
-
+/* This looks for the first double new line in the data stream.
+ It also indexes the tags in the section. */
bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength)
{
const char *End = Start + MaxLength;
diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h
index 321329a23..f63a51d07 100644
--- a/apt-pkg/tagfile.h
+++ b/apt-pkg/tagfile.h
@@ -33,7 +33,18 @@ class pkgTagSection
unsigned int AlphaIndexes[0x100];
unsigned int TagCount;
-
+
+ /* This very simple hash function for the last 8 letters gives
+ very good performance on the debian package files */
+ inline static unsigned long AlphaHash(const char *Text, const char *End = 0)
+ {
+ unsigned long Res = 0;
+ for (; Text != End && *Text != ':' && *Text != 0; Text++)
+ Res = ((unsigned long)(*Text) & 0xDF) ^ (Res << 1);
+ return Res & 0xFF;
+ }
+
+
protected:
const char *Stop;
@@ -54,6 +65,8 @@ class pkgTagSection
virtual void TrimRecord(bool BeforeRecord, const char* &End);
inline unsigned int Count() const {return TagCount;};
+ inline bool Exists(const char* const Tag) {return AlphaIndexes[AlphaHash(Tag)] != 0;}
+
inline void Get(const char *&Start,const char *&Stop,unsigned int I) const
{Start = Section + Indexes[I]; Stop = Section + Indexes[I+1];}