From 319790f4f86f595724fb2bd5aa6274d345469010 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 20 Mar 2012 19:23:32 +0100 Subject: * methods/rred.cc: - check return of writev() as gcc recommends * methods/mirror.cc: - check return of chdir() as gcc recommends * apt-pkg/deb/dpkgpm.cc: - check return of write() a gcc recommends * apt-inst/deb/debfile.cc: - check return of chdir() as gcc recommends * apt-inst/deb/dpkgdb.cc: - check return of chdir() as gcc recommends --- apt-pkg/deb/dpkgpm.cc | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index c46a81209..63c5a6380 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -163,6 +163,25 @@ pkgCache::VerIterator FindNowVersion(const pkgCache::PkgIterator &Pkg) return Ver; } /*}}}*/ +ssize_t retry_write(int fd, const void *buf, size_t count) +{ + int Res; + ssize_t i = 0; + errno = 0; + do + { + Res = write(fd, buf, count); + if (Res < 0 && errno == EINTR) + continue; + if (Res < 0) + break; + buf = (char *)buf + Res; + count -= Res; + i += Res; + } + while (Res > 0 && count > 0); + return i; +} // DPkgPM::pkgDPkgPM - Constructor /*{{{*/ // --------------------------------------------------------------------- @@ -425,7 +444,7 @@ void pkgDPkgPM::DoStdin(int master) unsigned char input_buf[256] = {0,}; ssize_t len = read(0, input_buf, sizeof(input_buf)); if (len) - write(master, input_buf, len); + retry_write(master, input_buf, len); else d->stdin_is_dev_null = true; } @@ -451,7 +470,7 @@ void pkgDPkgPM::DoTerminalPty(int master) } if(len <= 0) return; - write(1, term_buf, len); + retry_write(1, term_buf, len); if(d->term_out) fwrite(term_buf, len, sizeof(char), d->term_out); } @@ -526,7 +545,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) << ":" << s << endl; if(OutStatusFd > 0) - write(OutStatusFd, status.str().c_str(), status.str().size()); + retry_write(OutStatusFd, status.str().c_str(), status.str().size()); if (Debug == true) std::clog << "send: '" << status.str() << "'" << endl; @@ -550,7 +569,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) << ":" << list[3] << endl; if(OutStatusFd > 0) - write(OutStatusFd, status.str().c_str(), status.str().size()); + retry_write(OutStatusFd, status.str().c_str(), status.str().size()); if (Debug == true) std::clog << "send: '" << status.str() << "'" << endl; pkgFailures++; @@ -564,7 +583,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) << ":" << list[3] << endl; if(OutStatusFd > 0) - write(OutStatusFd, status.str().c_str(), status.str().size()); + retry_write(OutStatusFd, status.str().c_str(), status.str().size()); if (Debug == true) std::clog << "send: '" << status.str() << "'" << endl; return; @@ -592,7 +611,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) << ":" << s << endl; if(OutStatusFd > 0) - write(OutStatusFd, status.str().c_str(), status.str().size()); + retry_write(OutStatusFd, status.str().c_str(), status.str().size()); if (Debug == true) std::clog << "send: '" << status.str() << "'" << endl; } @@ -1055,7 +1074,8 @@ bool pkgDPkgPM::Go(int OutStatusFd) } int fd[2]; - pipe(fd); + if (pipe(fd) != 0) + return _error->Errno("pipe","Failed to create IPC pipe to dpkg"); #define ADDARG(X) Args.push_back(X); Size += strlen(X) #define ADDARGC(X) Args.push_back(X); Size += sizeof(X) - 1 @@ -1236,7 +1256,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) << (PackagesDone/float(PackagesTotal)*100.0) << ":" << _("Running dpkg") << endl; - write(OutStatusFd, status.str().c_str(), status.str().size()); + retry_write(OutStatusFd, status.str().c_str(), status.str().size()); } Child = ExecFork(); -- cgit v1.2.3-70-g09d2 From 136a6c13c8df7c403dd5284ff8bda20c8a84b614 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 22 Mar 2012 22:18:05 +0100 Subject: make these retry_write methods static so that they don't end up as symbols --- apt-pkg/deb/dpkgpm.cc | 3 ++- methods/rred.cc | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 63c5a6380..1a21c03eb 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -163,7 +163,8 @@ pkgCache::VerIterator FindNowVersion(const pkgCache::PkgIterator &Pkg) return Ver; } /*}}}*/ -ssize_t retry_write(int fd, const void *buf, size_t count) +static ssize_t +retry_write(int fd, const void *buf, size_t count) { int Res; ssize_t i = 0; diff --git a/methods/rred.cc b/methods/rred.cc index 38554464d..78d1595d4 100644 --- a/methods/rred.cc +++ b/methods/rred.cc @@ -227,7 +227,7 @@ struct EdCommand { char type; }; #define IOV_COUNT 1024 /* Don't really want IOV_MAX since it can be arbitrarily large */ -ssize_t retry_writev(int fd, const struct iovec *iov, int iovcnt) { +static ssize_t retry_writev(int fd, const struct iovec *iov, int iovcnt) { ssize_t Res; errno = 0; ssize_t i = 0; -- cgit v1.2.3-70-g09d2 From d68d65ad637526e46ea77ab83e07470d26df15fc Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 11 Apr 2012 13:25:28 +0200 Subject: use a static FileFd::Write overload to reduce duplication of write()-retry code --- apt-pkg/acquire-worker.cc | 27 +++------------------------ apt-pkg/acquire.cc | 16 +--------------- apt-pkg/contrib/fileutl.cc | 22 ++++++++++++++++++++++ apt-pkg/contrib/fileutl.h | 1 + apt-pkg/deb/dpkgpm.cc | 34 +++++++--------------------------- debian/libapt-pkg4.12.symbols | 1 + 6 files changed, 35 insertions(+), 66 deletions(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/acquire-worker.cc b/apt-pkg/acquire-worker.cc index d79b2b16d..77e2fc311 100644 --- a/apt-pkg/acquire-worker.cc +++ b/apt-pkg/acquire-worker.cc @@ -433,21 +433,7 @@ bool pkgAcquire::Worker::MediaChange(string Message) << endl; std::string const dlstatus = status.str(); - size_t done = 0; - size_t todo = dlstatus.size(); - errno = 0; - int res = 0; - do - { - res = write(status_fd, dlstatus.c_str() + done, todo); - if (res < 0 && errno == EINTR) - continue; - if (res < 0) - break; - done += res; - todo -= res; - } - while (res > 0 && todo > 0); + FileFd::Write(status_fd, dlstatus.c_str(), dlstatus.size()); } if (Log == 0 || Log->MediaChange(LookupTag(Message,"Media"), @@ -546,17 +532,10 @@ bool pkgAcquire::Worker::QueueItem(pkgAcquire::Queue::QItem *Item) /* */ bool pkgAcquire::Worker::OutFdReady() { - int Res; - do - { - Res = write(OutFd,OutQueue.c_str(),OutQueue.length()); - } - while (Res < 0 && errno == EINTR); - - if (Res <= 0) + if (FileFd::Write(OutFd,OutQueue.c_str(),OutQueue.length()) == false) return MethodFailure(); - OutQueue.erase(0,Res); + OutQueue.clear(); if (OutQueue.empty() == true) OutReady = false; diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index 19bcca8a1..5e1419056 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -874,21 +874,7 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner) << endl; std::string const dlstatus = status.str(); - size_t done = 0; - size_t todo = dlstatus.size(); - errno = 0; - int res = 0; - do - { - res = write(fd, dlstatus.c_str() + done, todo); - if (res < 0 && errno == EINTR) - continue; - if (res < 0) - break; - done += res; - todo -= res; - } - while (res > 0 && todo > 0); + FileFd::Write(fd, dlstatus.c_str(), dlstatus.size()); } return true; diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 536571fee..9e3611b26 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -1301,6 +1301,28 @@ bool FileFd::Write(const void *From,unsigned long long Size) Flags |= Fail; return _error->Error(_("write, still have %llu to write but couldn't"), Size); +} +bool FileFd::Write(int Fd, const void *From, unsigned long long Size) +{ + int Res; + errno = 0; + do + { + Res = write(Fd,From,Size); + if (Res < 0 && errno == EINTR) + continue; + if (Res < 0) + return _error->Errno("write",_("Write error")); + + From = (char *)From + Res; + Size -= Res; + } + while (Res > 0 && Size > 0); + + if (Size == 0) + return true; + + return _error->Error(_("write, still have %llu to write but couldn't"), Size); } /*}}}*/ // FileFd::Seek - Seek in the file /*{{{*/ diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index 1ca41cb7d..426664d3a 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -78,6 +78,7 @@ class FileFd bool Read(void *To,unsigned long long Size,unsigned long long *Actual = 0); char* ReadLine(char *To, unsigned long long const Size); bool Write(const void *From,unsigned long long Size); + bool static Write(int Fd, const void *From, unsigned long long Size); bool Seek(unsigned long long To); bool Skip(unsigned long long To); bool Truncate(unsigned long long To); diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 1a21c03eb..496daf1df 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -163,26 +163,6 @@ pkgCache::VerIterator FindNowVersion(const pkgCache::PkgIterator &Pkg) return Ver; } /*}}}*/ -static ssize_t -retry_write(int fd, const void *buf, size_t count) -{ - int Res; - ssize_t i = 0; - errno = 0; - do - { - Res = write(fd, buf, count); - if (Res < 0 && errno == EINTR) - continue; - if (Res < 0) - break; - buf = (char *)buf + Res; - count -= Res; - i += Res; - } - while (Res > 0 && count > 0); - return i; -} // DPkgPM::pkgDPkgPM - Constructor /*{{{*/ // --------------------------------------------------------------------- @@ -445,7 +425,7 @@ void pkgDPkgPM::DoStdin(int master) unsigned char input_buf[256] = {0,}; ssize_t len = read(0, input_buf, sizeof(input_buf)); if (len) - retry_write(master, input_buf, len); + FileFd::Write(master, input_buf, len); else d->stdin_is_dev_null = true; } @@ -471,7 +451,7 @@ void pkgDPkgPM::DoTerminalPty(int master) } if(len <= 0) return; - retry_write(1, term_buf, len); + FileFd::Write(1, term_buf, len); if(d->term_out) fwrite(term_buf, len, sizeof(char), d->term_out); } @@ -546,7 +526,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) << ":" << s << endl; if(OutStatusFd > 0) - retry_write(OutStatusFd, status.str().c_str(), status.str().size()); + FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); if (Debug == true) std::clog << "send: '" << status.str() << "'" << endl; @@ -570,7 +550,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) << ":" << list[3] << endl; if(OutStatusFd > 0) - retry_write(OutStatusFd, status.str().c_str(), status.str().size()); + FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); if (Debug == true) std::clog << "send: '" << status.str() << "'" << endl; pkgFailures++; @@ -584,7 +564,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) << ":" << list[3] << endl; if(OutStatusFd > 0) - retry_write(OutStatusFd, status.str().c_str(), status.str().size()); + FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); if (Debug == true) std::clog << "send: '" << status.str() << "'" << endl; return; @@ -612,7 +592,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) << ":" << s << endl; if(OutStatusFd > 0) - retry_write(OutStatusFd, status.str().c_str(), status.str().size()); + FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); if (Debug == true) std::clog << "send: '" << status.str() << "'" << endl; } @@ -1257,7 +1237,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) << (PackagesDone/float(PackagesTotal)*100.0) << ":" << _("Running dpkg") << endl; - retry_write(OutStatusFd, status.str().c_str(), status.str().size()); + FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); } Child = ExecFork(); diff --git a/debian/libapt-pkg4.12.symbols b/debian/libapt-pkg4.12.symbols index 012617eb6..1abf22899 100644 --- a/debian/libapt-pkg4.12.symbols +++ b/debian/libapt-pkg4.12.symbols @@ -1524,6 +1524,7 @@ libapt-pkg.so.4.12 libapt-pkg4.12 #MINVER# (c++)"GetListOfFilesInDir(std::basic_string, std::allocator > const&, bool)@Base" 0.8.16~exp13 (c++)"pkgCache::DepIterator::IsIgnorable(pkgCache::PkgIterator const&) const@Base" 0.8.16~exp10 (c++)"pkgCache::DepIterator::IsIgnorable(pkgCache::PrvIterator const&) const@Base" 0.8.16~exp10 + (c++)"FileFd::Write(int, void const*, unsigned long long)@Base" 0.8.16~exp14 (c++|optional=private)"pkgCacheGenerator::MergeListGroup(pkgCacheGenerator::ListParser&, std::basic_string, std::allocator > const&)@Base" 0.8.16~exp7 (c++|optional=private)"pkgCacheGenerator::MergeListPackage(pkgCacheGenerator::ListParser&, pkgCache::PkgIterator&)@Base" 0.8.16~exp7 (c++|optional=private)"pkgCacheGenerator::MergeListVersion(pkgCacheGenerator::ListParser&, pkgCache::PkgIterator&, std::basic_string, std::allocator > const&, pkgCache::VerIterator*&)@Base" 0.8.16~exp7 -- cgit v1.2.3-70-g09d2 From d4621f8277a76f3e5c87b06f7abd93df04446efc Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 20 Apr 2012 09:12:56 +0200 Subject: cherry pick r1975 from lp:~ubuntu-core-dev/apt/ubuntu --- apt-pkg/deb/dpkgpm.cc | 1 + debian/changelog | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index be11870fd..14376f649 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -738,6 +738,7 @@ bool pkgDPkgPM::OpenLog() d->history_out = fopen(history_name.c_str(),"a"); if (d->history_out == NULL) return _error->WarningE("OpenLog", _("Could not open file '%s'"), history_name.c_str()); + SetCloseExec(fileno(d->history_out), true); chmod(history_name.c_str(), 0644); fprintf(d->history_out, "\nStart-Date: %s\n", timestr); string remove, purge, install, reinstall, upgrade, downgrade; diff --git a/debian/changelog b/debian/changelog index 50d6ea3ce..fa4cdc251 100644 --- a/debian/changelog +++ b/debian/changelog @@ -121,6 +121,12 @@ apt (0.8.16~exp13) experimental; urgency=low -- Michael Vogt Tue, 06 Mar 2012 18:12:57 +0100 +apt (0.8.16~exp12ubuntu8) precise; urgency=low + + * Set FD_CLOEXEC on history.log's FD (Closes: #610069, LP: #636010) + + -- Adam Conrad Thu, 12 Apr 2012 16:26:20 -0600 + apt (0.8.16~exp12) experimental; urgency=low [ Michael Vogt ] -- cgit v1.2.3-70-g09d2 From 92f212774bebbff6aabd3081910f570a77180911 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 3 Sep 2012 13:03:02 +0200 Subject: report the package name with architecture in the "no file" error message --- apt-pkg/deb/dpkgpm.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 296426c80..ae9143e0d 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -187,7 +187,7 @@ pkgDPkgPM::~pkgDPkgPM() bool pkgDPkgPM::Install(PkgIterator Pkg,string File) { if (File.empty() == true || Pkg.end() == true) - return _error->Error("Internal Error, No file name for %s",Pkg.Name()); + return _error->Error("Internal Error, No file name for %s",Pkg.FullName().c_str()); // If the filename string begins with DPkg::Chroot-Directory, return the // substr that is within the chroot so dpkg can access it. -- cgit v1.2.3-70-g09d2 From c919ad6e4d0de48acb60f2a1371ade9bfb0451f8 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 9 Sep 2012 16:03:52 +0200 Subject: handle packages without a mandatory architecture (debian-policy §5.3) by introducing a pseudo-architecture 'none' so that the small group of users with these packages can get right of them without introducing too much hassle for other users (Closes: #686346) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apt-pkg/algorithms.cc | 5 ++ apt-pkg/deb/deblistparser.cc | 22 +++++- apt-pkg/deb/dpkgpm.cc | 8 +- apt-pkg/pkgcache.cc | 6 +- apt-pkg/pkgcachegen.cc | 53 ++++++++++++- debian/changelog | 4 + test/integration/framework | 12 +-- .../test-bug-686346-package-missing-architecture | 87 ++++++++++++++++++++++ 8 files changed, 183 insertions(+), 14 deletions(-) create mode 100755 test/integration/test-bug-686346-package-missing-architecture (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 2f5fcc7ab..1b0161ffd 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -194,6 +194,11 @@ bool pkgSimulate::Remove(PkgIterator iPkg,bool Purge) { // Adapt the iterator PkgIterator Pkg = Sim.FindPkg(iPkg.Name(), iPkg.Arch()); + if (Pkg.end() == true) + { + std::cerr << (Purge ? "Purg" : "Remv") << " invalid package " << iPkg.FullName() << std::endl; + return false; + } Flags[Pkg->ID] = 3; Sim.MarkDelete(Pkg); diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 12c6ab4c9..b84bd6fdd 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -645,6 +645,8 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver, a != Architectures.end(); ++a) if (NewDepends(Ver,Package,*a,Version,Op,Type) == false) return false; + if (NewDepends(Ver,Package,"none",Version,Op,Type) == false) + return false; } else if (MultiArchEnabled == true && found != string::npos && strcmp(Package.c_str() + found, ":any") != 0) @@ -658,8 +660,18 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver, if (NewDepends(Ver,Package,Arch,Version,Op,Type) == false) return false; } - else if (NewDepends(Ver,Package,pkgArch,Version,Op,Type) == false) - return false; + else + { + if (NewDepends(Ver,Package,pkgArch,Version,Op,Type) == false) + return false; + if ((Type == pkgCache::Dep::Conflicts || + Type == pkgCache::Dep::DpkgBreaks || + Type == pkgCache::Dep::Replaces) && + NewDepends(Ver, Package, + (pkgArch != "none") ? "none" : _config->Find("APT::Architecture"), + Version,Op,Type) == false) + return false; + } if (Start == Stop) break; } @@ -753,13 +765,15 @@ bool debListParser::Step() drop the whole section. A missing arch tag only happens (in theory) inside the Status file, so that is a positive return */ string const Architecture = Section.FindS("Architecture"); - if (Architecture.empty() == true) - return true; if (Arch.empty() == true || Arch == "any" || MultiArchEnabled == false) { if (APT::Configuration::checkArchitecture(Architecture) == true) return true; + /* parse version stanzas without an architecture only in the status file + (and as misfortune bycatch flat-archives) */ + if ((Arch.empty() == true || Arch == "any") && Architecture.empty() == true) + return true; } else { diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index ae9143e0d..c9df41d3a 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1131,7 +1131,9 @@ bool pkgDPkgPM::Go(int OutStatusFd) if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.Name()) != disappearedPkgs.end()) continue; // We keep this here to allow "smooth" transitions from e.g. multiarch dpkg/ubuntu to dpkg/debian - if (dpkgMultiArch == false && (I->Pkg.Arch() == nativeArch || !strcmp(I->Pkg.Arch(), "all"))) + if (dpkgMultiArch == false && (I->Pkg.Arch() == nativeArch || + strcmp(I->Pkg.Arch(), "all") == 0 || + strcmp(I->Pkg.Arch(), "none") == 0)) { char const * const name = I->Pkg.Name(); ADDARG(name); @@ -1148,7 +1150,9 @@ bool pkgDPkgPM::Go(int OutStatusFd) } else PkgVer = Cache[I->Pkg].InstVerIter(Cache); - if (PkgVer.end() == false) + if (strcmp(I->Pkg.Arch(), "none") == 0) + ; // never arch-qualify a package without an arch + else if (PkgVer.end() == false) name.append(":").append(PkgVer.Arch()); else _error->Warning("Can not find PkgVer for '%s'", name.c_str()); diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 9acb7da72..353172d8a 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -238,7 +238,7 @@ pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) { // --------------------------------------------------------------------- /* Returns 0 on error, pointer to the package otherwise */ pkgCache::PkgIterator pkgCache::FindPkg(const string &Name, string const &Arch) { - if (MultiArchCache() == false) { + if (MultiArchCache() == false && Arch != "none") { if (Arch == "native" || Arch == "all" || Arch == "any" || Arch == NativeArch()) return SingleArchFindPkg(Name); @@ -376,6 +376,10 @@ pkgCache::PkgIterator pkgCache::GrpIterator::FindPreferredPkg(bool const &Prefer if (Pkg.end() == false && (PreferNonVirtual == false || Pkg->VersionList != 0)) return Pkg; } + // packages without an architecture + Pkg = FindPkg("none"); + if (Pkg.end() == false && (PreferNonVirtual == false || Pkg->VersionList != 0)) + return Pkg; if (PreferNonVirtual == true) return FindPreferredPkg(false); diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index f70cbd02a..490c2ecbb 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -200,7 +200,19 @@ bool pkgCacheGenerator::MergeList(ListParser &List, } if (Arch.empty() == true) - Arch = _config->Find("APT::Architecture"); + { + // use the pseudo arch 'none' for arch-less packages + Arch = "none"; + /* We might built a SingleArchCache here, which we don't want to blow up + just for these :none packages to a proper MultiArchCache, so just ensure + that we have always a native package structure first for SingleArch */ + pkgCache::PkgIterator NP; + if (NewPackage(NP, PackageName, _config->Find("APT::Architecture")) == false) + // TRANSLATOR: The first placeholder is a package name, + // the other two should be copied verbatim as they include debug info + return _error->Error(_("Error occurred while processing %s (%s%d)"), + PackageName.c_str(), "NewPackage", 0); + } // Get a pointer to the package structure pkgCache::PkgIterator Pkg; @@ -418,6 +430,42 @@ bool pkgCacheGenerator::MergeListVersion(ListParser &List, pkgCache::PkgIterator return _error->Error(_("Error occurred while processing %s (%s%d)"), Pkg.Name(), "AddImplicitDepends", 1); } + /* :none packages are packages without an architecture. They are forbidden by + debian-policy, so usually they will only be in (old) dpkg status files - + and dpkg will complain about them - and are pretty rare. We therefore do + usually not create conflicts while the parent is created, but only if a :none + package (= the target) appears. This creates incorrect dependencies on :none + for architecture-specific dependencies on the package we copy from, but we + will ignore this bug as architecture-specific dependencies are only allowed + in jessie and until then the :none packages should be extinct (hopefully). + In other words: This should work long enough to allow graceful removal of + these packages, it is not supposed to allow users to keep using them … */ + if (strcmp(Pkg.Arch(), "none") == 0) + { + pkgCache::PkgIterator M = Grp.FindPreferredPkg(); + if (M.end() == false && Pkg != M) + { + pkgCache::DepIterator D = M.RevDependsList(); + Dynamic DynD(D); + for (; D.end() == false; ++D) + { + if ((D->Type != pkgCache::Dep::Conflicts && + D->Type != pkgCache::Dep::DpkgBreaks && + D->Type != pkgCache::Dep::Replaces) || + D.ParentPkg().Group() == Grp) + continue; + + map_ptrloc *OldDepLast = NULL; + pkgCache::VerIterator ConVersion = D.ParentVer(); + // duplicate the Conflicts/Breaks/Replaces for :none arch + if (D->Version == 0) + NewDepends(Pkg, ConVersion, "", 0, D->Type, OldDepLast); + else + NewDepends(Pkg, ConVersion, D.TargetVer(), + D->CompareOp, D->Type, OldDepLast); + } + } + } } if (unlikely(AddImplicitDepends(Grp, Pkg, Ver) == false)) return _error->Error(_("Error occurred while processing %s (%s%d)"), @@ -871,6 +919,9 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator &Ver, // Locate the target package pkgCache::PkgIterator Pkg = Grp.FindPkg(Arch); + // we don't create 'none' packages and their dependencies if we can avoid it … + if (Pkg.end() == true && Arch == "none") + return true; Dynamic DynPkg(Pkg); if (Pkg.end() == true) { if (unlikely(Owner->NewPackage(Pkg, PackageName, Arch) == false)) diff --git a/debian/changelog b/debian/changelog index e62f0b681..90f3199b3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,10 @@ apt (0.9.7.5) UNRELEASED; urgency=low * Japanese (KURASAWA Nozomu) (Closes: #684435) [ David Kalnischkies ] + * handle packages without a mandatory architecture (debian-policy §5.3) + by introducing a pseudo-architecture 'none' so that the small group of + users with these packages can get right of them without introducing too + much hassle for other users (Closes: #686346) * apt-pkg/cdrom.cc: - copy only configured translation files from a CD-ROM and not all available translation files preventing new installs with d-i from diff --git a/test/integration/framework b/test/integration/framework index 57bf555af..1c4872c8e 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -468,7 +468,7 @@ insertpackage() { local PRIORITY="${6:-optional}" local ARCHS="" for arch in $(echo "$ARCH" | sed -e 's#,#\n#g' | sed -e "s#^native\$#$(getarchitecture 'native')#"); do - if [ "$arch" = "all" ]; then + if [ "$arch" = 'all' -o "$arch" = 'none' ]; then ARCHS="$(getarchitectures)" else ARCHS="$arch" @@ -482,9 +482,9 @@ insertpackage() { Priority: $PRIORITY Section: other Installed-Size: 42 -Maintainer: Joe Sixpack -Architecture: $arch -Version: $VERSION +Maintainer: Joe Sixpack " >> $FILE + test "$arch" = 'none' || echo "Architecture: $arch" >> $FILE + echo "Version: $VERSION Filename: pool/main/${NAME}/${NAME}_${VERSION}_${arch}.deb" >> $FILE test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> $FILE echo "Description: an autogenerated dummy ${NAME}=${VERSION}/${RELEASE} @@ -534,8 +534,8 @@ Priority: $PRIORITY Section: other Installed-Size: 42 Maintainer: Joe Sixpack -Architecture: $arch Version: $VERSION" >> $FILE + test "$arch" = 'none' || echo "Architecture: $arch" >> $FILE test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> $FILE echo "Description: an autogenerated dummy ${NAME}=${VERSION}/installed If you find such a package installed on your system, @@ -818,7 +818,7 @@ testnopackage() { testdpkginstalled() { msgtest "Test for correctly installed package(s) with" "dpkg -l $*" - local PKGS="$(dpkg -l $* | grep '^i' | wc -l)" + local PKGS="$(dpkg -l $* 2>/dev/null | grep '^i' | wc -l)" if [ "$PKGS" != $# ]; then echo $PKGS dpkg -l $* | grep '^[a-z]' diff --git a/test/integration/test-bug-686346-package-missing-architecture b/test/integration/test-bug-686346-package-missing-architecture new file mode 100755 index 000000000..b0e0aa3c4 --- /dev/null +++ b/test/integration/test-bug-686346-package-missing-architecture @@ -0,0 +1,87 @@ +#!/bin/sh +set -e + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework +setupenvironment +configarchitecture 'amd64' + +insertinstalledpackage 'pkgb' 'none' '1' +insertinstalledpackage 'pkgd' 'none' '1' +insertpackage 'unstable' 'pkga' 'amd64' '2' 'Depends: pkgb' +insertpackage 'unstable' 'pkgb' 'amd64' '2' +insertpackage 'unstable' 'pkgc' 'amd64' '1' 'Conflicts: pkgb' +insertpackage 'unstable' 'pkge' 'none' '1' + +setupaptarchive + +testequal 'Reading package lists... +Building dependency tree... +The following packages will be REMOVED: + pkgb:none +The following NEW packages will be installed: + pkgc +0 upgraded, 1 newly installed, 1 to remove and 0 not upgraded. +Remv pkgb:none [1] +Inst pkgc (1 unstable [amd64]) +Conf pkgc (1 unstable [amd64])' aptget install pkgc -s + +testequal 'Reading package lists... +Building dependency tree... +The following extra packages will be installed: + pkgb +The following packages will be REMOVED: + pkgb:none +The following NEW packages will be installed: + pkga pkgb +0 upgraded, 2 newly installed, 1 to remove and 0 not upgraded. +Remv pkgb:none [1] +Inst pkgb (2 unstable [amd64]) +Inst pkga (2 unstable [amd64]) +Conf pkgb (2 unstable [amd64]) +Conf pkga (2 unstable [amd64])' aptget install pkga -s + +# ensure that arch-less stanzas from Packages files are ignored +msgtest 'Package is distributed in the Packages files' 'pkge' +grep -q 'Package: pkge' $(find aptarchive -name 'Packages') && msgpass || msgfail +testnopackage pkge +testnopackage pkge:none +testnopackage pkge:* + +# do not automatically change from none-arch to whatever-arch as +# this breaks other none packages and dpkg has this ruleset as +# this difference seems so important that it has to be maintained … +testequal 'Reading package lists... +Building dependency tree... +0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.' aptget dist-upgrade -s + +# pkgd has no update with an architecture +testdpkginstalled pkgd +msgtest 'Test apt-get purge' 'pkgd' +aptget purge pkgd -y >/dev/null 2>&1 && msgpass || msgfail +testdpkgnotinstalled pkgd + +# there is a pkgb with an architecture +testdpkginstalled pkgb +msgtest 'Test apt-get purge' 'pkgb:none' +aptget purge pkgb:none -y >/dev/null 2>&1 && msgpass || msgfail +testdpkgnotinstalled pkgb + +# check that dependencies are created after the none package exists in the cache +rm rootdir/var/cache/apt/*.bin +insertinstalledpackage 'pkgb' 'none' '1' +insertinstalledpackage 'pkgf' 'none' '1' 'Conflicts: pkgb' +insertinstalledpackage 'pkgg' 'amd64' '1' 'Conflicts: pkgb' +insertinstalledpackage 'pkgb' 'amd64' '2' +testequal "Reading package lists... +Building dependency tree... +Reading state information... +You might want to run 'apt-get -f install' to correct these. +The following packages have unmet dependencies: + pkgb : Conflicts: pkgb:none but 1 is installed + pkgb:none : Conflicts: pkgb but 2 is installed + pkgf:none : Conflicts: pkgb:none but 1 is installed + Conflicts: pkgb but 2 is installed + pkgg : Conflicts: pkgb but 2 is installed + Conflicts: pkgb:none but 1 is installed +E: Unmet dependencies. Try using -f." aptget check -- cgit v1.2.3-70-g09d2 From fb3ecf163485c428ebf863e65e60ec884e741ada Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 13 Dec 2012 09:02:04 +0100 Subject: change permissions of /var/log/apt/term.log to 0640 (LP: #975199) --- apt-pkg/deb/dpkgpm.cc | 2 +- debian/apt.postinst | 7 +++++++ debian/changelog | 5 ++++- 3 files changed, 12 insertions(+), 2 deletions(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index c9df41d3a..6cb8bc6b6 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -726,7 +726,7 @@ bool pkgDPkgPM::OpenLog() gr = getgrnam("adm"); if (pw != NULL && gr != NULL) chown(logfile_name.c_str(), pw->pw_uid, gr->gr_gid); - chmod(logfile_name.c_str(), 0644); + chmod(logfile_name.c_str(), 0640); fprintf(d->term_out, "\nLog started: %s\n", timestr); } diff --git a/debian/apt.postinst b/debian/apt.postinst index 4d87c4e25..bd814e1af 100644 --- a/debian/apt.postinst +++ b/debian/apt.postinst @@ -21,6 +21,13 @@ case "$1" in rm -f $SECRING fi apt-key update + + # ensure tighter permissons on the logs, see LP: #975199 + if dpkg --compare-versions "$2" lt-nl 0.9.7.7; then + # ensure permissions are right + chmod -f 0640 /var/log/apt/term.log* || true + fi + ;; abort-upgrade|abort-remove|abort-deconfigure) diff --git a/debian/changelog b/debian/changelog index a189695ec..42d601d3b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -13,8 +13,11 @@ apt (0.9.7.7) UNRELEASED; urgency=low - do not do lock-step configuration for a M-A:same package if it isn't unpacked yet in SmartConfigure and do not unpack a M-A:same package again in SmartUnPack if we have already configured it (LP: #1062503) + + [ Michael Vogt ] + * change permissions of /var/log/apt/term.log to 0640 (LP: #975199) - -- Jordi Mallach Thu, 18 Oct 2012 23:30:46 +0200 + -- Michael Vogt Tue, 04 Dec 2012 15:57:01 +0100 apt (0.9.7.6) unstable; urgency=low -- cgit v1.2.3-70-g09d2