From: David Kalnischkies Date: Wed, 14 Sep 2011 18:22:31 +0000 (+0200) Subject: enable APT in unpack/configure ordering to handle loops as well X-Git-Tag: 0.9.0~53^2 X-Git-Url: https://git.saurik.com/apt.git/commitdiff_plain/75a90b93257ea81d42331c03b56bd6589c62e065?ds=inline;hp=-c enable APT in unpack/configure ordering to handle loops as well as tight dependencies between immediate packages better enabling also the possibility to mark all packages as immediate (at least Closes: #353290, #540227, #559733, #621836, #639290) --- 75a90b93257ea81d42331c03b56bd6589c62e065 diff --combined apt-pkg/deb/dpkgpm.cc index 2c34465c0,57361ccdc..0cc21f322 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@@ -8,8 -8,6 +8,8 @@@ ##################################################################### */ /*}}}*/ // Includes /*{{{*/ +#include + #include #include #include @@@ -18,6 -16,7 +18,7 @@@ #include #include #include + #include #include #include @@@ -42,26 -41,12 +43,26 @@@ #include #include -#include #include /*}}}*/ using namespace std; +class pkgDPkgPMPrivate +{ +public: + pkgDPkgPMPrivate() : dpkgbuf_pos(0), term_out(NULL), history_out(NULL) + { + } + bool stdin_is_dev_null; + // the buffer we use for the dpkg status-fd reading + char dpkgbuf[1024]; + int dpkgbuf_pos; + FILE *term_out; + FILE *history_out; + string dpkg_error; +}; + namespace { // Maps the dpkg "processing" info to human readable names. Entry 0 @@@ -126,9 -111,9 +127,9 @@@ ionice(int PID // --------------------------------------------------------------------- /* */ pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) - : pkgPackageManager(Cache), dpkgbuf_pos(0), - term_out(NULL), history_out(NULL), PackagesDone(0), PackagesTotal(0) + : pkgPackageManager(Cache), PackagesDone(0), PackagesTotal(0) { + d = new pkgDPkgPMPrivate(); } /*}}}*/ // DPkgPM::pkgDPkgPM - Destructor /*{{{*/ @@@ -136,7 -121,6 +137,7 @@@ /* */ pkgDPkgPM::~pkgDPkgPM() { + delete d; } /*}}}*/ // DPkgPM::Install - Install a package /*{{{*/ @@@ -230,7 -214,7 +231,7 @@@ bool pkgDPkgPM::SendV2Pkgs(FILE *F fprintf(F,"\n"); // Write out the package actions in order. - for (vector::iterator I = List.begin(); I != List.end(); I++) + for (vector::iterator I = List.begin(); I != List.end(); ++I) { if(I->Pkg.end() == true) continue; @@@ -352,7 -336,7 +353,7 @@@ bool pkgDPkgPM::RunScriptsWithPkgs(cons // Feed it the filenames. if (Version <= 1) { - for (vector::iterator I = List.begin(); I != List.end(); I++) + for (vector::iterator I = List.begin(); I != List.end(); ++I) { // Only deal with packages to be installed from .deb if (I->Op != Item::Install) @@@ -393,7 -377,7 +394,7 @@@ void pkgDPkgPM::DoStdin(int master if (len) write(master, input_buf, len); else - stdin_is_dev_null = true; + d->stdin_is_dev_null = true; } /*}}}*/ // DPkgPM::DoTerminalPty - Read the terminal pty and write log /*{{{*/ @@@ -418,8 -402,8 +419,8 @@@ void pkgDPkgPM::DoTerminalPty(int maste if(len <= 0) return; write(1, term_buf, len); - if(term_out) - fwrite(term_buf, len, sizeof(char), term_out); + if(d->term_out) + fwrite(term_buf, len, sizeof(char), d->term_out); } /*}}}*/ // DPkgPM::ProcessDpkgStatusBuf /*{{{*/ @@@ -623,14 -607,14 +624,14 @@@ void pkgDPkgPM::DoDpkgStatusFd(int stat char *p, *q; int len; - len=read(statusfd, &dpkgbuf[dpkgbuf_pos], sizeof(dpkgbuf)-dpkgbuf_pos); - dpkgbuf_pos += len; + len=read(statusfd, &d->dpkgbuf[d->dpkgbuf_pos], sizeof(d->dpkgbuf)-d->dpkgbuf_pos); + d->dpkgbuf_pos += len; if(len <= 0) return; // process line by line if we have a buffer - p = q = dpkgbuf; - while((q=(char*)memchr(p, '\n', dpkgbuf+dpkgbuf_pos-p)) != NULL) + p = q = d->dpkgbuf; + while((q=(char*)memchr(p, '\n', d->dpkgbuf+d->dpkgbuf_pos-p)) != NULL) { *q = 0; ProcessDpkgStatusLine(OutStatusFd, p); @@@ -638,8 -622,8 +639,8 @@@ } // now move the unprocessed bits (after the final \n that is now a 0x0) - // to the start and update dpkgbuf_pos - p = (char*)memrchr(dpkgbuf, 0, dpkgbuf_pos); + // to the start and update d->dpkgbuf_pos + p = (char*)memrchr(d->dpkgbuf, 0, d->dpkgbuf_pos); if(p == NULL) return; @@@ -647,8 -631,8 +648,8 @@@ p++; // move the unprocessed tail to the start and update pos - memmove(dpkgbuf, p, p-dpkgbuf); - dpkgbuf_pos = dpkgbuf+dpkgbuf_pos-p; + memmove(d->dpkgbuf, p, p-d->dpkgbuf); + d->dpkgbuf_pos = d->dpkgbuf+d->dpkgbuf_pos-p; } /*}}}*/ // DPkgPM::WriteHistoryTag /*{{{*/ @@@ -660,7 -644,7 +661,7 @@@ void pkgDPkgPM::WriteHistoryTag(string // poor mans rstrip(", ") if (value[length-2] == ',' && value[length-1] == ' ') value.erase(length - 2, 2); - fprintf(history_out, "%s: %s\n", tag.c_str(), value.c_str()); + fprintf(d->history_out, "%s: %s\n", tag.c_str(), value.c_str()); } /*}}}*/ // DPkgPM::OpenLog /*{{{*/ bool pkgDPkgPM::OpenLog() @@@ -681,11 -665,11 +682,11 @@@ _config->Find("Dir::Log::Terminal")); if (!logfile_name.empty()) { - term_out = fopen(logfile_name.c_str(),"a"); - if (term_out == NULL) + d->term_out = fopen(logfile_name.c_str(),"a"); + if (d->term_out == NULL) return _error->WarningE("OpenLog", _("Could not open file '%s'"), logfile_name.c_str()); - setvbuf(term_out, NULL, _IONBF, 0); - SetCloseExec(fileno(term_out), true); + setvbuf(d->term_out, NULL, _IONBF, 0); + SetCloseExec(fileno(d->term_out), true); struct passwd *pw; struct group *gr; pw = getpwnam("root"); @@@ -693,7 -677,7 +694,7 @@@ if (pw != NULL && gr != NULL) chown(logfile_name.c_str(), pw->pw_uid, gr->gr_gid); chmod(logfile_name.c_str(), 0644); - fprintf(term_out, "\nLog started: %s\n", timestr); + fprintf(d->term_out, "\nLog started: %s\n", timestr); } // write your history @@@ -701,13 -685,13 +702,13 @@@ _config->Find("Dir::Log::History")); if (!history_name.empty()) { - history_out = fopen(history_name.c_str(),"a"); - if (history_out == NULL) + 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()); chmod(history_name.c_str(), 0644); - fprintf(history_out, "\nStart-Date: %s\n", timestr); + fprintf(d->history_out, "\nStart-Date: %s\n", timestr); string remove, purge, install, reinstall, upgrade, downgrade; - for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) { enum { CANDIDATE, CANDIDATE_AUTO, CURRENT_CANDIDATE, CURRENT } infostring; string *line = NULL; @@@ -746,7 -730,7 +747,7 @@@ WriteHistoryTag("Downgrade",downgrade); WriteHistoryTag("Remove",remove); WriteHistoryTag("Purge",purge); - fflush(history_out); + fflush(d->history_out); } return true; @@@ -760,16 -744,16 +761,16 @@@ bool pkgDPkgPM::CloseLog( struct tm *tmp = localtime(&t); strftime(timestr, sizeof(timestr), "%F %T", tmp); - if(term_out) + if(d->term_out) { - fprintf(term_out, "Log ended: "); - fprintf(term_out, "%s", timestr); - fprintf(term_out, "\n"); - fclose(term_out); + fprintf(d->term_out, "Log ended: "); + fprintf(d->term_out, "%s", timestr); + fprintf(d->term_out, "\n"); + fclose(d->term_out); } - term_out = NULL; + d->term_out = NULL; - if(history_out) + if(d->history_out) { if (disappearedPkgs.empty() == false) { @@@ -786,12 -770,12 +787,12 @@@ } WriteHistoryTag("Disappeared", disappear); } - if (dpkg_error.empty() == false) - fprintf(history_out, "Error: %s\n", dpkg_error.c_str()); - fprintf(history_out, "End-Date: %s\n", timestr); - fclose(history_out); + if (d->dpkg_error.empty() == false) + fprintf(d->history_out, "Error: %s\n", d->dpkg_error.c_str()); + fprintf(d->history_out, "End-Date: %s\n", timestr); + fclose(d->history_out); } - history_out = NULL; + d->history_out = NULL; return true; } @@@ -885,21 -869,21 +886,21 @@@ bool pkgDPkgPM::Go(int OutStatusFd // that will be [installed|configured|removed|purged] and add // them to the PackageOps map (the dpkg states it goes through) // and the PackageOpsTranslations (human readable strings) - for (vector::const_iterator I = List.begin(); I != List.end();I++) + for (vector::const_iterator I = List.begin(); I != List.end(); ++I) { if((*I).Pkg.end() == true) continue; string const name = (*I).Pkg.Name(); PackageOpsDone[name] = 0; - for(int i=0; (DpkgStatesOpMap[(*I).Op][i]).state != NULL; i++) + for(int i=0; (DpkgStatesOpMap[(*I).Op][i]).state != NULL; ++i) { PackageOps[name].push_back(DpkgStatesOpMap[(*I).Op][i]); PackagesTotal++; } } - stdin_is_dev_null = false; + d->stdin_is_dev_null = false; // create log OpenLog(); @@@ -910,7 -894,7 +911,7 @@@ // Do all actions with the same Op in one run vector::const_iterator J = I; if (TriggersPending == true) - for (; J != List.end(); J++) + for (; J != List.end(); ++J) { if (J->Op == I->Op) continue; @@@ -922,7 -906,7 +923,7 @@@ break; } else - for (; J != List.end() && J->Op == I->Op; J++) + for (; J != List.end() && J->Op == I->Op; ++J) /* nothing */; // Generate the argument list @@@ -937,7 -921,7 +938,7 @@@ // the argument list is split in a way that A depends on B // and they are in the same "--configure A B" run // - with the split they may now be configured in different - // runs + // runs, using Immediate-Configure-All can help prevent this. if (J - I > (signed)MaxArgs) J = I + MaxArgs; @@@ -970,6 -954,8 +971,8 @@@ snprintf(status_fd_buf,sizeof(status_fd_buf),"%i", fd[1]); Args[n++] = status_fd_buf; Size += strlen(Args[n-1]); + + unsigned long const Op = I->Op; switch (I->Op) { @@@ -1028,7 -1014,7 +1031,7 @@@ // Write in the file or package names if (I->Op == Item::Install) { - for (;I != J && Size < MaxArgBytes; I++) + for (;I != J && Size < MaxArgBytes; ++I) { if (I->File[0] != '/') return _error->Error("Internal Error, Pathname to install is not absolute '%s'",I->File.c_str()); @@@ -1040,7 -1026,7 +1043,7 @@@ { string const nativeArch = _config->Find("APT::Architecture"); unsigned long const oldSize = I->Op == Item::Configure ? Size : 0; - for (;I != J && Size < MaxArgBytes; I++) + for (;I != J && Size < MaxArgBytes; ++I) { if((*I).Pkg.end() == true) continue; @@@ -1079,8 -1065,13 +1082,13 @@@ it to all processes in the group. Since dpkg ignores the signal it doesn't die but we do! So we must also ignore it */ sighandler_t old_SIGQUIT = signal(SIGQUIT,SIG_IGN); - sighandler_t old_SIGINT = signal(SIGINT,SIG_IGN); - + sighandler_t old_SIGINT = signal(SIGINT,SigINT); + + // Check here for any SIGINT + if (pkgPackageManager::SigINTStop && (Op == Item::Remove || Op == Item::Purge || Op == Item::Install)) + break; + + // ignore SIGHUP as well (debian #463030) sighandler_t old_SIGHUP = signal(SIGHUP,SIG_IGN); @@@ -1099,8 -1090,8 +1107,8 @@@ const char *s = _("Can not write log, openpty() " "failed (/dev/pts not mounted?)\n"); fprintf(stderr, "%s",s); - if(term_out) - fprintf(term_out, "%s",s); + if(d->term_out) + fprintf(d->term_out, "%s",s); master = slave = -1; } else { struct termios rtt; @@@ -1118,7 -1109,6 +1126,6 @@@ sigprocmask(SIG_SETMASK, &original_sigmask, 0); } } - // Fork dpkg pid_t Child; _config->Set("APT::Keep-Fds::",fd[1]); @@@ -1224,13 -1214,14 +1231,14 @@@ // Restore sig int/quit signal(SIGQUIT,old_SIGQUIT); signal(SIGINT,old_SIGINT); + signal(SIGHUP,old_SIGHUP); return _error->Errno("waitpid","Couldn't wait for subprocess"); } // wait for input or output here FD_ZERO(&rfds); - if (master >= 0 && !stdin_is_dev_null) + if (master >= 0 && !d->stdin_is_dev_null) FD_SET(0, &rfds); FD_SET(_dpkgin, &rfds); if(master >= 0) @@@ -1264,6 -1255,7 +1272,7 @@@ // Restore sig int/quit signal(SIGQUIT,old_SIGQUIT); signal(SIGINT,old_SIGINT); + signal(SIGHUP,old_SIGHUP); if(master >= 0) @@@ -1284,14 -1276,14 +1293,14 @@@ RunScripts("DPkg::Post-Invoke"); if (WIFSIGNALED(Status) != 0 && WTERMSIG(Status) == SIGSEGV) - strprintf(dpkg_error, "Sub-process %s received a segmentation fault.",Args[0]); + strprintf(d->dpkg_error, "Sub-process %s received a segmentation fault.",Args[0]); else if (WIFEXITED(Status) != 0) - strprintf(dpkg_error, "Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status)); + strprintf(d->dpkg_error, "Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status)); else - strprintf(dpkg_error, "Sub-process %s exited unexpectedly",Args[0]); + strprintf(d->dpkg_error, "Sub-process %s exited unexpectedly",Args[0]); - if(dpkg_error.size() > 0) - _error->Error("%s", dpkg_error.c_str()); + if(d->dpkg_error.size() > 0) + _error->Error("%s", d->dpkg_error.c_str()); if(stopOnError) { @@@ -1301,6 -1293,9 +1310,9 @@@ } } CloseLog(); + + if (pkgPackageManager::SigINTStop) + _error->Warning(_("Operation was interrupted before it could finish")); if (RunScripts("DPkg::Post-Invoke") == false) return false; @@@ -1325,6 -1320,11 +1337,11 @@@ Cache.writeStateFile(NULL); return true; } + + void SigINT(int sig) { + if (_config->FindB("APT::Immediate-Configure-All",false)) + pkgPackageManager::SigINTStop = true; + } /*}}}*/ // pkgDpkgPM::Reset - Dump the contents of the command list /*{{{*/ // --------------------------------------------------------------------- @@@ -1455,8 -1455,8 +1472,8 @@@ void pkgDPkgPM::WriteApportReport(cons fprintf(report, "ErrorMessage:\n %s\n", errormsg); // ensure that the log is flushed - if(term_out) - fflush(term_out); + if(d->term_out) + fflush(d->term_out); // attach terminal log it if we have it string logfile_name = _config->FindFile("Dir::Log::Terminal"); @@@ -1478,7 -1478,7 +1495,7 @@@ // log the ordering const char *ops_str[] = {"Install", "Configure","Remove","Purge"}; fprintf(report, "AptOrdering:\n"); - for (vector::iterator I = List.begin(); I != List.end(); I++) + for (vector::iterator I = List.begin(); I != List.end(); ++I) fprintf(report, " %s: %s\n", (*I).Pkg.Name(), ops_str[(*I).Op]); // attach dmesg log (to learn about segfaults) diff --combined apt-pkg/deb/dpkgpm.h index ddf9485c7,fb92c58ea..3f95c51dc --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@@ -18,12 -18,19 +18,12 @@@ using std::vector; using std::map; +class pkgDPkgPMPrivate; class pkgDPkgPM : public pkgPackageManager { private: - - bool stdin_is_dev_null; - - // the buffer we use for the dpkg status-fd reading - char dpkgbuf[1024]; - int dpkgbuf_pos; - FILE *term_out; - FILE *history_out; - string dpkg_error; + pkgDPkgPMPrivate *d; /** \brief record the disappear action and handle accordingly @@@ -106,4 -113,6 +106,6 @@@ virtual ~pkgDPkgPM(); }; + void SigINT(int sig); + #endif diff --combined apt-pkg/orderlist.cc index 80d7b6619,1e412ead5..0ac9a83e3 --- a/apt-pkg/orderlist.cc +++ b/apt-pkg/orderlist.cc @@@ -63,8 -63,6 +63,8 @@@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ +#include + #include #include #include @@@ -147,14 -145,14 +147,14 @@@ bool pkgOrderList::DoRun( Depth = 0; WipeFlags(Added | AddPending | Loop | InList); - for (iterator I = List; I != End; I++) + for (iterator I = List; I != End; ++I) Flag(*I,InList); // Rebuild the main list into the temp list. iterator OldEnd = End; End = NList; - for (iterator I = List; I != OldEnd; I++) - if (VisitNode(PkgIterator(Cache,*I)) == false) + for (iterator I = List; I != OldEnd; ++I) + if (VisitNode(PkgIterator(Cache,*I), "DoRun") == false) { End = OldEnd; return false; @@@ -199,7 -197,7 +199,7 @@@ bool pkgOrderList::OrderCritical( { clog << "** Critical Unpack ordering done" << endl; - for (iterator I = List; I != End; I++) + for (iterator I = List; I != End; ++I) { PkgIterator P(Cache,*I); if (IsNow(P) == true) @@@ -224,7 -222,7 +224,7 @@@ bool pkgOrderList::OrderUnpack(string * WipeFlags(After); // Set the inlist flag - for (iterator I = List; I != End; I++) + for (iterator I = List; I != End; ++I) { PkgIterator P(Cache,*I); if (IsMissing(P) == true && IsNow(P) == true) @@@ -272,7 -270,7 +272,7 @@@ { clog << "** Unpack ordering done" << endl; - for (iterator I = List; I != End; I++) + for (iterator I = List; I != End; ++I) { PkgIterator P(Cache,*I); if (IsNow(P) == true) @@@ -325,7 -323,7 +325,7 @@@ int pkgOrderList::Score(PkgIterator Pkg Score += ScoreImmediate; for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); - D.end() == false; D++) + D.end() == false; ++D) if (D->Type == pkgCache::Dep::PreDepends) { Score += ScorePreDepends; @@@ -490,76 -488,40 +490,76 @@@ bool pkgOrderList::VisitRProvides(DepFu return true; bool Res = true; - for (PrvIterator P = Ver.ProvidesList(); P.end() == false; P++) + for (PrvIterator P = Ver.ProvidesList(); P.end() == false; ++P) Res &= (this->*F)(P.ParentPkg().RevDependsList()); return Res; } /*}}}*/ // OrderList::VisitProvides - Visit all of the providing packages /*{{{*/ // --------------------------------------------------------------------- -/* This routine calls visit on all providing packages. */ +/* This routine calls visit on all providing packages. + + If the dependency is negative it first visits packages which are + intended to be removed and after that all other packages. + It does so to avoid situations in which this package is used to + satisfy a (or-group/provides) dependency of another package which + could have been satisfied also by upgrading another package - + otherwise we have more broken packages dpkg needs to auto- + deconfigure and in very complicated situations it even decides + against it! */ bool pkgOrderList::VisitProvides(DepIterator D,bool Critical) -{ +{ SPtrArray List = D.AllTargets(); - for (Version **I = List; *I != 0; I++) + for (Version **I = List; *I != 0; ++I) { VerIterator Ver(Cache,*I); PkgIterator Pkg = Ver.ParentPkg(); + if (D.IsNegative() == true && Cache[Pkg].Delete() == false) + continue; + if (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing) continue; - + if (D.IsNegative() == false && Cache[Pkg].InstallVer != *I) continue; - + if (D.IsNegative() == true && (Version *)Pkg.CurrentVer() != *I) continue; - + + // Skip over missing files + if (Critical == false && IsMissing(D.ParentPkg()) == true) + continue; + + if (VisitNode(Pkg, "Provides-1") == false) + return false; + } + if (D.IsNegative() == false) + return true; + for (Version **I = List; *I != 0; ++I) + { + VerIterator Ver(Cache,*I); + PkgIterator Pkg = Ver.ParentPkg(); + + if (Cache[Pkg].Delete() == true) + continue; + + if (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing) + continue; + + if ((Version *)Pkg.CurrentVer() != *I) + continue; + // Skip over missing files if (Critical == false && IsMissing(D.ParentPkg()) == true) continue; - if (VisitNode(Pkg) == false) + if (VisitNode(Pkg, "Provides-2") == false) return false; } + return true; } /*}}}*/ @@@ -568,7 -530,7 +568,7 @@@ /* This is the core ordering routine. It calls the set dependency consideration functions which then potentialy call this again. Finite depth is achived through the colouring mechinism. */ -bool pkgOrderList::VisitNode(PkgIterator Pkg) +bool pkgOrderList::VisitNode(PkgIterator Pkg, char const* from) { // Looping or irrelevent. // This should probably trancend not installed packages @@@ -579,7 -541,7 +579,7 @@@ if (Debug == true) { for (int j = 0; j != Depth; j++) clog << ' '; - clog << "Visit " << Pkg.FullName() << endl; + clog << "Visit " << Pkg.FullName() << " from " << from << endl; } Depth++; @@@ -653,7 -615,7 +653,7 @@@ Loops are preprocessed and logged. */ bool pkgOrderList::DepUnPackCrit(DepIterator D) { - for (; D.end() == false; D++) + for (; D.end() == false; ++D) { if (D.Reverse() == true) { @@@ -674,7 -636,7 +674,7 @@@ if (CheckDep(D) == true) continue; - if (VisitNode(D.ParentPkg()) == false) + if (VisitNode(D.ParentPkg(), "UnPackCrit") == false) return false; } else @@@ -731,7 -693,7 +731,7 @@@ bool pkgOrderList::DepUnPackPreD(DepIte if (D.Reverse() == true) return DepUnPackCrit(D); - for (; D.end() == false; D++) + for (; D.end() == false; ++D) { if (D.IsCritical() == false) continue; @@@ -774,7 -736,7 +774,7 @@@ bool pkgOrderList::DepUnPackPre(DepIter if (D.Reverse() == true) return true; - for (; D.end() == false; D++) + for (; D.end() == false; ++D) { /* Only consider the PreDepends or Depends. Depends are only considered at the lowest depth or in the case of immediate @@@ -829,7 -791,7 +829,7 @@@ bool pkgOrderList::DepUnPackDep(DepIterator D) { - for (; D.end() == false; D++) + for (; D.end() == false; ++D) if (D.IsCritical() == true) { if (D.Reverse() == true) @@@ -849,7 -811,7 +849,7 @@@ if (IsMissing(D.ParentPkg()) == true) continue; - if (VisitNode(D.ParentPkg()) == false) + if (VisitNode(D.ParentPkg(), "UnPackDep-Parent") == false) return false; } else @@@ -863,7 -825,7 +863,7 @@@ if (CheckDep(D) == true) continue; - if (VisitNode(D.TargetPkg()) == false) + if (VisitNode(D.TargetPkg(), "UnPackDep-Target") == false) return false; } } @@@ -884,7 -846,7 +884,7 @@@ bool pkgOrderList::DepConfigure(DepIter if (D.Reverse() == true) return true; - for (; D.end() == false; D++) + for (; D.end() == false; ++D) if (D->Type == pkgCache::Dep::Depends) if (VisitProvides(D,false) == false) return false; @@@ -906,7 -868,7 +906,7 @@@ bool pkgOrderList::DepRemove(DepIterato { if (D.Reverse() == false) return true; - for (; D.end() == false; D++) + for (; D.end() == false; ++D) if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) { // Duplication elimination, consider the current version only @@@ -962,7 -924,7 +962,7 @@@ if (IsFlag(P, InList) == true && IsFlag(P, AddPending) == false && Cache[P].InstallVer != 0 && - VisitNode(P) == true) + VisitNode(P, "Remove-P") == true) { Flag(P, Immediate); tryFixDeps = false; @@@ -998,7 -960,7 +998,7 @@@ if (IsFlag(F.TargetPkg(), InList) == true && IsFlag(F.TargetPkg(), AddPending) == false && Cache[F.TargetPkg()].InstallVer != 0 && - VisitNode(F.TargetPkg()) == true) + VisitNode(F.TargetPkg(), "Remove-Target") == true) { Flag(F.TargetPkg(), Immediate); tryFixDeps = false; @@@ -1012,7 -974,7 +1012,7 @@@ if (IsFlag(Prv.OwnerPkg(), InList) == true && IsFlag(Prv.OwnerPkg(), AddPending) == false && Cache[Prv.OwnerPkg()].InstallVer != 0 && - VisitNode(Prv.OwnerPkg()) == true) + VisitNode(Prv.OwnerPkg(), "Remove-Owner") == true) { Flag(Prv.OwnerPkg(), Immediate); tryFixDeps = false; @@@ -1032,7 -994,7 +1032,7 @@@ if (IsMissing(D.ParentPkg()) == true) continue; - if (VisitNode(D.ParentPkg()) == false) + if (VisitNode(D.ParentPkg(), "Remove-Parent") == false) return false; } @@@ -1059,8 -1021,10 +1059,10 @@@ bool pkgOrderList::AddLoop(DepIterator Loops[LoopCount++] = D; // Mark the packages as being part of a loop. - Flag(D.TargetPkg(),Loop); - Flag(D.ParentPkg(),Loop); + //Flag(D.TargetPkg(),Loop); + //Flag(D.ParentPkg(),Loop); + /* This is currently disabled because the Loop flag is being used for + loop management in the package manager. Check the orderlist.h file for more info */ return true; } /*}}}*/ @@@ -1111,7 -1075,7 +1113,7 @@@ bool pkgOrderList::CheckDep(DepIterato just needs one */ if (D.IsNegative() == false) { - // ignore provides by older versions of this package + // ignore provides by older versions of this package if (((D.Reverse() == false && Pkg == D.ParentPkg()) || (D.Reverse() == true && Pkg == D.TargetPkg())) && Cache[Pkg].InstallVer != *I) diff --combined apt-pkg/orderlist.h index 264f7ba03,4e5ea1654..9588d30a5 --- a/apt-pkg/orderlist.h +++ b/apt-pkg/orderlist.h @@@ -18,7 -18,6 +18,7 @@@ #include +#include class pkgDepCache; class pkgOrderList : protected pkgCache::Namespace @@@ -46,8 -45,7 +46,8 @@@ bool Debug; // Main visit function - bool VisitNode(PkgIterator Pkg); + __deprecated bool VisitNode(PkgIterator Pkg) { return VisitNode(Pkg, "UNKNOWN"); }; + bool VisitNode(PkgIterator Pkg, char const* from); bool VisitDeps(DepFunc F,PkgIterator Pkg); bool VisitRDeps(DepFunc F,PkgIterator Pkg); bool VisitRProvides(DepFunc F,VerIterator Ver); @@@ -76,7 -74,12 +76,12 @@@ typedef Package **iterator; - // State flags + /* State flags + The Loop flag can be set on a package that is currently being processed by either SmartConfigure or + SmartUnPack. This allows the package manager to tell when a loop has been formed as it will try to + SmartUnPack or SmartConfigure a package with the Loop flag set. It will then either stop (as it knows + that the operation is unnecessary as its already in process), or in the case of the conflicts resolution + in SmartUnPack, use EarlyRemove to resolve the situation. */ enum Flags {Added = (1 << 0), AddPending = (1 << 1), Immediate = (1 << 2), Loop = (1 << 3), UnPacked = (1 << 4), Configured = (1 << 5), @@@ -91,6 -94,9 +96,9 @@@ void Flag(PkgIterator Pkg,unsigned long State, unsigned long F) {Flags[Pkg->ID] = (Flags[Pkg->ID] & (~F)) | State;}; inline void Flag(PkgIterator Pkg,unsigned long F) {Flags[Pkg->ID] |= F;}; inline void Flag(Package *Pkg,unsigned long F) {Flags[Pkg->ID] |= F;}; + // RmFlag removes a flag from a package + inline void RmFlag(Package *Pkg,unsigned long F) {Flags[Pkg->ID] &= ~F;}; + // IsNow will return true if the Pkg has been not been either configured or unpacked inline bool IsNow(PkgIterator Pkg) {return (Flags[Pkg->ID] & (States & (~Removed))) == 0;}; bool IsMissing(PkgIterator Pkg); void WipeFlags(unsigned long F); diff --combined apt-pkg/packagemanager.cc index c41a1f1ee,b5d353602..3cd9f6f00 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@@ -13,8 -13,6 +13,8 @@@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ +#include + #include #include #include @@@ -24,13 -22,15 +24,15 @@@ #include #include #include - -#include + +#include #include -#include +#include /*}}}*/ using namespace std; + bool pkgPackageManager::SigINTStop = false; + // PM::PackageManager - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ @@@ -65,7 -65,7 +67,7 @@@ bool pkgPackageManager::GetArchives(pkg if (ordering == false) return _error->Error("Internal ordering error"); - for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++) + for (pkgOrderList::iterator I = List->begin(); I != List->end(); ++I) { PkgIterator Pkg(Cache,*I); FileNames[Pkg->ID] = string(); @@@ -101,7 -101,7 +103,7 @@@ bool pkgPackageManager::FixMissing( List->SetFileList(FileNames); bool Bad = false; - for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + for (PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) { if (List->IsMissing(I) == false) continue; @@@ -142,7 -142,7 +144,7 @@@ void pkgPackageManager::ImmediateAdd(Pk D = I.CurrentVer().DependsList(); } - for ( /* nothing */ ; D.end() == false; D++) + for ( /* nothing */ ; D.end() == false; ++D) if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) { if(!List->IsFlag(D.TargetPkg(), pkgOrderList::Immediate)) @@@ -168,29 -168,35 +170,35 @@@ bool pkgPackageManager::CreateOrderList delete List; List = new pkgOrderList(&Cache); - static bool const NoImmConfigure = !_config->FindB("APT::Immediate-Configure",true); + NoImmConfigure = !_config->FindB("APT::Immediate-Configure",true); + ImmConfigureAll = _config->FindB("APT::Immediate-Configure-All",false); + + if (Debug && ImmConfigureAll) + clog << "CreateOrderList(): Adding Immediate flag for all packages because of APT::Immediate-Configure-All" << endl; // Generate the list of affected packages and sort it - for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + for (PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) { // Ignore no-version packages if (I->VersionList == 0) continue; // Mark the package and its dependends for immediate configuration - if (((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential || + if ((((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential || (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) && - NoImmConfigure == false) + NoImmConfigure == false) || ImmConfigureAll) { - if(Debug) + if(Debug && !ImmConfigureAll) clog << "CreateOrderList(): Adding Immediate flag for " << I.Name() << endl; List->Flag(I,pkgOrderList::Immediate); - - // Look for other install packages to make immediate configurea - ImmediateAdd(I, true); - // And again with the current version. - ImmediateAdd(I, false); + if (!ImmConfigureAll) { + // Look for other install packages to make immediate configurea + ImmediateAdd(I, true); + + // And again with the current version. + ImmediateAdd(I, false); + } } // Not interesting @@@ -231,7 -237,7 +239,7 @@@ bool pkgPackageManager::DepAlwaysTrue(D bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg,DepIterator D, const char *Ver) { - for (;D.end() == false; D++) + for (;D.end() == false; ++D) { if (D->Type != pkgCache::Dep::Conflicts && D->Type != pkgCache::Dep::Obsoletes) @@@ -258,13 -264,14 +266,14 @@@ // PM::ConfigureAll - Run the all out configuration /*{{{*/ // --------------------------------------------------------------------- /* This configures every package. It is assumed they are all unpacked and - that the final configuration is valid. */ + that the final configuration is valid. This is also used to catch packages + that have not been configured when using ImmConfigureAll */ bool pkgPackageManager::ConfigureAll() { pkgOrderList OList(&Cache); // Populate the order list - for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++) + for (pkgOrderList::iterator I = List->begin(); I != List->end(); ++I) if (List->IsFlag(pkgCache::PkgIterator(Cache,*I), pkgOrderList::UnPacked) == true) OList.push_back(*I); @@@ -276,12 -283,22 +285,22 @@@ bool const ConfigurePkgs = (conf == "all"); // Perform the configuring - for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++) + for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); ++I) { PkgIterator Pkg(Cache,*I); + + /* Check if the package has been configured, this can happen if SmartConfigure + calls its self */ + if (List->IsFlag(Pkg,pkgOrderList::Configured)) continue; - if (ConfigurePkgs == true && Configure(Pkg) == false) + if (ConfigurePkgs == true && SmartConfigure(Pkg, 0) == false) { + if (ImmConfigureAll) + _error->Error(_("Could not perform immediate configuration on '%s'. " + "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),1); + else + _error->Error("Internal error, packages left unconfigured. %s",Pkg.Name()); return false; + } List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); } @@@ -291,37 -308,143 +310,143 @@@ /*}}}*/ // PM::SmartConfigure - Perform immediate configuration of the pkg /*{{{*/ // --------------------------------------------------------------------- - /* This routine scheduals the configuration of the given package and all - of it's dependents. */ - bool pkgPackageManager::SmartConfigure(PkgIterator Pkg) + /* This function tries to put the system in a state where Pkg can be configured. + This involves checking each of Pkg's dependanies and unpacking and + configuring packages where needed. + + Note on failure: This method can fail, without causing any problems. + This can happen when using Immediate-Configure-All, SmartUnPack may call + SmartConfigure, it may fail because of a complex dependancy situation, but + a error will only be reported if ConfigureAll fails. This is why some of the + messages this function reports on failure (return false;) as just warnings + only shown when debuging*/ + bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth) { - if (Debug == true) - clog << "SmartConfigure " << Pkg.Name() << endl; + // If this is true, only check and correct and dependancies without the Loop flag + bool PkgLoop = List->IsFlag(Pkg,pkgOrderList::Loop); + + if (Debug) { + VerIterator InstallVer = VerIterator(Cache,Cache[Pkg].InstallVer); + clog << OutputInDepth(Depth) << "SmartConfigure " << Pkg.Name() << " (" << InstallVer.VerStr() << ")"; + if (PkgLoop) + clog << " (Only Correct Dependancies)"; + clog << endl; + } - pkgOrderList OList(&Cache); + VerIterator const instVer = Cache[Pkg].InstVerIter(Cache); + + /* Because of the ordered list, most dependancies should be unpacked, + however if there is a loop (A depends on B, B depends on A) this will not + be the case, so check for dependancies before configuring. */ + bool Bad = false; + for (DepIterator D = instVer.DependsList(); + D.end() == false; ) + { + // Compute a single dependency element (glob or) + pkgCache::DepIterator Start; + pkgCache::DepIterator End; + D.GlobOr(Start,End); + + if (End->Type == pkgCache::Dep::Depends) + Bad = true; + + // Check for dependanices that have not been unpacked, probably due to loops. + while (End->Type == pkgCache::Dep::Depends) { + PkgIterator DepPkg; + VerIterator InstallVer; + SPtrArray VList = Start.AllTargets(); + + // Check through each version of each package that could satisfy this dependancy + for (Version **I = VList; *I != 0; I++) { + VerIterator Ver(Cache,*I); + DepPkg = Ver.ParentPkg(); + InstallVer = VerIterator(Cache,Cache[DepPkg].InstallVer); - if (DepAdd(OList,Pkg) == false) + // Check if the current version of the package is avalible and will satisfy this dependancy + if (DepPkg.CurrentVer() == Ver && List->IsNow(DepPkg) == true && + !List->IsFlag(DepPkg,pkgOrderList::Removed) && DepPkg.State() == PkgIterator::NeedsNothing) + { + Bad = false; + break; + } + + // Check if the version that is going to be installed will satisfy the dependancy + if (Cache[DepPkg].InstallVer == *I) { + if (List->IsFlag(DepPkg,pkgOrderList::UnPacked)) { + if (List->IsFlag(DepPkg,pkgOrderList::Loop) && PkgLoop) { + // This dependancy has already been dealt with by another SmartConfigure on Pkg + Bad = false; + break; + } else if (List->IsFlag(Pkg,pkgOrderList::Loop)) { + /* Check for a loop to prevent one forming + If A depends on B and B depends on A, SmartConfigure will + just hop between them if this is not checked. Dont remove the + loop flag after finishing however as loop is already set. + This means that there is another SmartConfigure call for this + package and it will remove the loop flag */ + Bad = !SmartConfigure(DepPkg, Depth + 1); + } else { + /* Check for a loop to prevent one forming + If A depends on B and B depends on A, SmartConfigure will + just hop between them if this is not checked */ + List->Flag(Pkg,pkgOrderList::Loop); + Bad = !SmartConfigure(DepPkg, Depth + 1); + List->RmFlag(Pkg,pkgOrderList::Loop); + } + // If SmartConfigure was succesfull, Bad is false, so break + if (!Bad) break; + } else if (List->IsFlag(DepPkg,pkgOrderList::Configured)) { + Bad = false; + break; + } + } + } + + /* If the dependany is still not satisfied, try, if possible, unpacking a package to satisfy it */ + if (InstallVer != 0 && Bad) { + Bad = false; + if (List->IsNow(DepPkg) && !List->IsFlag(DepPkg,pkgOrderList::Loop)) { + List->Flag(Pkg,pkgOrderList::Loop); + if (Debug) + cout << OutputInDepth(Depth) << "Unpacking " << DepPkg.Name() << " to avoid loop" << endl; + SmartUnPack(DepPkg, true, Depth + 1); + List->RmFlag(Pkg,pkgOrderList::Loop); + } + } + + if (Start==End) { + if (Bad && Debug) { + if (!List->IsFlag(DepPkg,pkgOrderList::Loop)) { + _error->Warning("Could not satisfy dependancies for %s",Pkg.Name()); + } + } + break; + } else { + Start++; + } + } + } + + if (Bad) { + if (Debug) + _error->Warning(_("Could not configure '%s'. "),Pkg.Name()); return false; + } + + if (PkgLoop) return true; static std::string const conf = _config->Find("PackageManager::Configure","all"); static bool const ConfigurePkgs = (conf == "all" || conf == "smart"); - if (ConfigurePkgs == true) - if (OList.OrderConfigure() == false) - return false; + if (List->IsFlag(Pkg,pkgOrderList::Configured)) + return _error->Error("Internal configure error on '%s'. ",Pkg.Name(),1); - // Perform the configuring - for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); ++I) - { - PkgIterator Pkg(Cache,*I); - - if (ConfigurePkgs == true && Configure(Pkg) == false) - return false; - - List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); - } + if (ConfigurePkgs == true && Configure(Pkg) == false) + return false; - ++ + List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); - if (Cache[Pkg].InstVerIter(Cache)->MultiArch == pkgCache::Version::Same) + if ((Cache[Pkg].InstVerIter(Cache)->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same) for (PkgIterator P = Pkg.Group().PackageList(); P.end() == false; P = Pkg.Group().NextPkg(P)) { @@@ -329,97 -452,16 +454,16 @@@ Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer && (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)) continue; - SmartConfigure(P); + SmartConfigure(P, (Depth +1)); } // Sanity Check if (List->IsFlag(Pkg,pkgOrderList::Configured) == false) - return _error->Error(_("Could not perform immediate configuration on '%s'. " - "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),1); + return _error->Error(_("Could not configure '%s'. "),Pkg.Name()); return true; } /*}}}*/ - // PM::DepAdd - Add all dependents to the oder list /*{{{*/ - // --------------------------------------------------------------------- - /* This recursively adds all dependents to the order list */ - bool pkgPackageManager::DepAdd(pkgOrderList &OList,PkgIterator Pkg,int Depth) - { - if (OList.IsFlag(Pkg,pkgOrderList::Added) == true) - return true; - if (List->IsFlag(Pkg,pkgOrderList::Configured) == true) - return true; - if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == false) - return false; - - if (Debug) - std::clog << OutputInDepth(Depth) << "DepAdd: " << Pkg.Name() << std::endl; - - // Put the package on the list - OList.push_back(Pkg); - OList.Flag(Pkg,pkgOrderList::Added); - Depth++; - - // Check the dependencies to see if they are all satisfied. - bool Bad = false; - for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); D.end() == false;) - { - if (D->Type != pkgCache::Dep::Depends && D->Type != pkgCache::Dep::PreDepends) - { - ++D; - continue; - } - - // Grok or groups - Bad = true; - for (bool LastOR = true; D.end() == false && LastOR == true; ++D) - { - LastOR = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or; - - if (Bad == false) - continue; - - SPtrArray VList = D.AllTargets(); - for (Version **I = VList; *I != 0 && Bad == true; ++I) - { - VerIterator Ver(Cache,*I); - PkgIterator Pkg = Ver.ParentPkg(); - - // See if the current version is ok - if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true && - Pkg.State() == PkgIterator::NeedsNothing) - { - Bad = false; - continue; - } - - // Not the install version - if (Cache[Pkg].InstallVer != *I || - (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing)) - continue; - - if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == true) - Bad = !DepAdd(OList,Pkg,Depth); - if (List->IsFlag(Pkg,pkgOrderList::Configured) == true) - Bad = false; - } - } - - if (Bad == true) - { - if (Debug) - std::clog << OutputInDepth(Depth) << "DepAdd FAILS on: " << Pkg.Name() << std::endl; - OList.Flag(Pkg,0,pkgOrderList::Added); - OList.pop_back(); - Depth--; - return false; - } - } - - Depth--; - return true; - } - /*}}}*/ // PM::EarlyRemove - Perform removal of packages before their time /*{{{*/ // --------------------------------------------------------------------- /* This is called to deal with conflicts arising from unpacking */ @@@ -446,7 -488,7 +490,7 @@@ bool pkgPackageManager::EarlyRemove(Pkg if (Pkg->CurrentVer != 0) { for (DepIterator D = Pkg.RevDependsList(); D.end() == false && - IsEssential == false; D++) + IsEssential == false; ++D) if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) if ((D.ParentPkg()->Flags & pkgCache::Flag::Essential) != 0) IsEssential = true; @@@ -485,30 -527,44 +529,44 @@@ bool pkgPackageManager::SmartRemove(Pkg /*}}}*/ // PM::SmartUnPack - Install helper /*{{{*/ // --------------------------------------------------------------------- - /* This performs the task of handling pre-depends. */ + /* This puts the system in a state where it can Unpack Pkg, if Pkg is allready + unpacked, or when it has been unpacked, if Immediate==true it configures it. */ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) { - return SmartUnPack(Pkg, true); + return SmartUnPack(Pkg, true, 0); } - bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate) + bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int const Depth) { + bool PkgLoop = List->IsFlag(Pkg,pkgOrderList::Loop); + + if (Debug) { + clog << OutputInDepth(Depth) << "SmartUnPack " << Pkg.Name(); + VerIterator InstallVer = VerIterator(Cache,Cache[Pkg].InstallVer); + if (Pkg.CurrentVer() == 0) + cout << " (install version " << InstallVer.VerStr() << ")"; + else + cout << " (replace version " << Pkg.CurrentVer().VerStr() << " with " << InstallVer.VerStr() << ")"; + if (PkgLoop) + cout << " (Only Perform PreUnpack Checks)"; + cout << endl; + } + // Check if it is already unpacked if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure && Cache[Pkg].Keep() == true) { - List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States); - if (Immediate == true && - List->IsFlag(Pkg,pkgOrderList::Immediate) == true) - if (SmartConfigure(Pkg) == false) - return _error->Error(_("Could not perform immediate configuration on already unpacked '%s'. " - "Please see man 5 apt.conf under APT::Immediate-Configure for details."),Pkg.Name()); - return true; + cout << OutputInDepth(Depth) << "SmartUnPack called on Package " << Pkg.Name() << " but its unpacked" << endl; + return false; } - + VerIterator const instVer = Cache[Pkg].InstVerIter(Cache); - /* See if this packages install version has any predependencies - that are not met by 'now' packages. */ + /* PreUnpack Checks: This loop checks and attempts to rectify and problems that would prevent the package being unpacked. + It addresses: PreDepends, Conflicts, Obsoletes and Breaks (DpkgBreaks). Any resolutions that do not require it should + avoid configuration (calling SmartUnpack with Immediate=true), this is because when unpacking some packages with + complex dependancy structures, trying to configure some packages while breaking the loops can complicate things . + This will be either dealt with if the package is configured as a dependency of Pkg (if and when Pkg is configured), + or by the ConfigureAll call at the end of the for loop in OrderInstall. */ for (DepIterator D = instVer.DependsList(); D.end() == false; ) { @@@ -519,8 -575,8 +577,8 @@@ while (End->Type == pkgCache::Dep::PreDepends) { - if (Debug == true) - clog << "PreDepends order for " << Pkg.Name() << std::endl; + if (Debug) + clog << OutputInDepth(Depth) << "PreDepends order for " << Pkg.Name() << std::endl; // Look for possible ok targets. SPtrArray VList = Start.AllTargets(); @@@ -535,8 -591,8 +593,8 @@@ Pkg.State() == PkgIterator::NeedsNothing) { Bad = false; - if (Debug == true) - clog << "Found ok package " << Pkg.Name() << endl; + if (Debug) + clog << OutputInDepth(Depth) << "Found ok package " << Pkg.Name() << endl; continue; } } @@@ -551,10 -607,15 +609,15 @@@ if (Cache[Pkg].InstallVer != *I || (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing)) continue; + + if (List->IsFlag(Pkg,pkgOrderList::Configured)) { + Bad = false; + continue; + } - if (Debug == true) - clog << "Trying to SmartConfigure " << Pkg.Name() << endl; - Bad = !SmartConfigure(Pkg); + if (Debug) + clog << OutputInDepth(Depth) << "Trying to SmartConfigure " << Pkg.Name() << endl; + Bad = !SmartConfigure(Pkg, Depth + 1); } /* If this or element did not match then continue on to the @@@ -566,9 -627,9 +629,9 @@@ return _error->Error("Couldn't configure pre-depend %s for %s, " "probably a dependency cycle.", End.TargetPkg().Name(),Pkg.Name()); - Start++; + ++Start; } - else + else break; } @@@ -581,71 -642,116 +644,139 @@@ for (Version **I = VList; *I != 0; I++) { VerIterator Ver(Cache,*I); - PkgIterator Pkg = Ver.ParentPkg(); + PkgIterator ConflictPkg = Ver.ParentPkg(); + VerIterator InstallVer(Cache,Cache[ConflictPkg].InstallVer); // See if the current version is conflicting - if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true) - { - if (EarlyRemove(Pkg) == false) - return _error->Error("Internal Error, Could not early remove %s",Pkg.Name()); + if (ConflictPkg.CurrentVer() == Ver && List->IsNow(ConflictPkg)) + { + cout << OutputInDepth(Depth) << Pkg.Name() << " conflicts with " << ConflictPkg.Name() << endl; + /* If a loop is not present or has not yet been detected, attempt to unpack packages + to resolve this conflict. If there is a loop present, remove packages to resolve this conflict */ + if (!List->IsFlag(ConflictPkg,pkgOrderList::Loop)) { + if (Cache[ConflictPkg].Keep() == 0 && Cache[ConflictPkg].InstallVer != 0) { + if (Debug) + cout << OutputInDepth(Depth) << OutputInDepth(Depth) << "Unpacking " << ConflictPkg.Name() << " to prevent conflict" << endl; + List->Flag(Pkg,pkgOrderList::Loop); + SmartUnPack(ConflictPkg,false, Depth + 1); + // Remove loop to allow it to be used later if needed + List->RmFlag(Pkg,pkgOrderList::Loop); + } else { + if (EarlyRemove(ConflictPkg) == false) + return _error->Error("Internal Error, Could not early remove %s",ConflictPkg.Name()); + } + } else { + if (!List->IsFlag(ConflictPkg,pkgOrderList::Removed)) { + if (Debug) + cout << OutputInDepth(Depth) << "Because of conficts knot, removing " << ConflictPkg.Name() << " to conflict violation" << endl; + if (EarlyRemove(ConflictPkg) == false) + return _error->Error("Internal Error, Could not early remove %s",ConflictPkg.Name()); + } + } + } + } + } + + // Check for breaks + if (End->Type == pkgCache::Dep::DpkgBreaks) { + SPtrArray VList = End.AllTargets(); + for (Version **I = VList; *I != 0; I++) + { + VerIterator Ver(Cache,*I); + PkgIterator BrokenPkg = Ver.ParentPkg(); + VerIterator InstallVer(Cache,Cache[BrokenPkg].InstallVer); + + // Check if it needs to be unpacked + if (List->IsFlag(BrokenPkg,pkgOrderList::InList) && Cache[BrokenPkg].Delete() == false && + List->IsNow(BrokenPkg)) { + if (List->IsFlag(BrokenPkg,pkgOrderList::Loop) && PkgLoop) { + // This dependancy has already been dealt with by another SmartUnPack on Pkg + break; + } else if (List->IsFlag(Pkg,pkgOrderList::Loop)) { + /* Found a break, so unpack the package, but dont remove loop as already set. + This means that there is another SmartUnPack call for this + package and it will remove the loop flag. */ + if (Debug) + cout << OutputInDepth(Depth) << " Unpacking " << BrokenPkg.Name() << " to avoid break" << endl; + + SmartUnPack(BrokenPkg, false, Depth + 1); + } else { + List->Flag(Pkg,pkgOrderList::Loop); + // Found a break, so unpack the package + if (Debug) + cout << OutputInDepth(Depth) << " Unpacking " << BrokenPkg.Name() << " to avoid break" << endl; + + SmartUnPack(BrokenPkg, false, Depth + 1); + List->RmFlag(Pkg,pkgOrderList::Loop); + } + } + + // Check if a package needs to be removed + if (Cache[BrokenPkg].Delete() == true && !List->IsFlag(BrokenPkg,pkgOrderList::Configured)) { + if (Debug) + cout << OutputInDepth(Depth) << " Removing " << BrokenPkg.Name() << " to avoid break" << endl; + SmartRemove(BrokenPkg); } } } } - + // Check for reverse conflicts. if (CheckRConflicts(Pkg,Pkg.RevDependsList(), instVer.VerStr()) == false) - return false; + return false; for (PrvIterator P = instVer.ProvidesList(); - P.end() == false; P++) - CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion()); + P.end() == false; ++P) + if (Pkg->Group != P.OwnerPkg()->Group) + CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion()); - if (PkgLoop) return true; ++ if (PkgLoop) ++ return true; + List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States); - if (instVer->MultiArch == pkgCache::Version::Same) + if (Immediate == true && instVer->MultiArch == pkgCache::Version::Same) + { + /* Do lockstep M-A:same unpacking in two phases: + First unpack all installed architectures, then the not installed. + This way we avoid that M-A: enabled packages are installed before + their older non-M-A enabled packages are replaced by newer versions */ + bool const installed = Pkg->CurrentVer != 0; + if (installed == true && Install(Pkg,FileNames[Pkg->ID]) == false) + return false; + for (PkgIterator P = Pkg.Group().PackageList(); + P.end() == false; P = Pkg.Group().NextPkg(P)) + { + if (P->CurrentVer == 0 || P == Pkg || List->IsFlag(P,pkgOrderList::UnPacked) == true || + Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer && + (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)) + continue; - if (SmartUnPack(P, false) == false) ++ if (SmartUnPack(P, false, Depth + 1) == false) + return false; + } + if (installed == false && Install(Pkg,FileNames[Pkg->ID]) == false) + return false; for (PkgIterator P = Pkg.Group().PackageList(); - P.end() == false; P = Pkg.Group().NextPkg(P)) + P.end() == false; P = Pkg.Group().NextPkg(P)) { - if (Pkg == P || List->IsFlag(P,pkgOrderList::UnPacked) == true || - Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer && - (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)) - continue; - SmartUnPack(P, false, Depth + 1); + if (P->CurrentVer != 0 || P == Pkg || List->IsFlag(P,pkgOrderList::UnPacked) == true || + Cache[P].InstallVer == 0 || (P.CurrentVer() == Cache[P].InstallVer && + (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall)) + continue; - if (SmartUnPack(P, false) == false) ++ if (SmartUnPack(P, false, Depth + 1) == false) + return false; } - - if(Install(Pkg,FileNames[Pkg->ID]) == false) + } + else if (Install(Pkg,FileNames[Pkg->ID]) == false) return false; - // Perform immedate configuration of the package. - if (Immediate == true && - List->IsFlag(Pkg,pkgOrderList::Immediate) == true) - if (SmartConfigure(Pkg) == false) - return _error->Error(_("Could not perform immediate configuration on '%s'. " - "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),2); + if (Immediate == true) { + // Perform immedate configuration of the package. + if (SmartConfigure(Pkg, Depth + 1) == false) + _error->Warning(_("Could not perform immediate configuration on '%s'. " + "Please see man 5 apt.conf under APT::Immediate-Configure for details. (%d)"),Pkg.Name(),2); + } return true; } @@@ -676,15 -782,22 +807,22 @@@ pkgPackageManager::OrderResult pkgPacka clog << "Done ordering" << endl; bool DoneSomething = false; - for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++) + for (pkgOrderList::iterator I = List->begin(); I != List->end(); ++I) { PkgIterator Pkg(Cache,*I); - + if (List->IsNow(Pkg) == false) { - if (Debug == true) - clog << "Skipping already done " << Pkg.Name() << endl; + if (!List->IsFlag(Pkg,pkgOrderList::Configured) && !NoImmConfigure) { + if (SmartConfigure(Pkg, 0) == false && Debug) + _error->Warning("Internal Error, Could not configure %s",Pkg.Name()); + // FIXME: The above warning message might need changing + } else { + if (Debug == true) + clog << "Skipping already done " << Pkg.Name() << endl; + } continue; + } if (List->IsMissing(Pkg) == true) @@@ -715,9 -828,16 +853,16 @@@ return Failed; } else - if (SmartUnPack(Pkg) == false) + if (SmartUnPack(Pkg,List->IsFlag(Pkg,pkgOrderList::Immediate),0) == false) return Failed; DoneSomething = true; + + if (ImmConfigureAll) { + /* ConfigureAll here to pick up and packages left unconfigured becuase they were unpacked in the + "PreUnpack Checks" section */ + if (!ConfigureAll()) + return Failed; + } } // Final run through the configure phase @@@ -725,7 -845,7 +870,7 @@@ return Failed; // Sanity check - for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++) + for (pkgOrderList::iterator I = List->begin(); I != List->end(); ++I) { if (List->IsFlag(*I,pkgOrderList::Configured) == false) { @@@ -733,7 -853,7 +878,7 @@@ PkgIterator(Cache,*I).Name()); return Failed; } - } + } return Completed; } @@@ -765,4 -885,4 +910,4 @@@ pkgPackageManager::OrderResult pkgPacka return DoInstallPostFork(statusFd); } - /*}}}*/ + /*}}}*/ diff --combined debian/changelog index 62bbdcdd8,87d25e78f..444a99ba7 --- a/debian/changelog +++ b/debian/changelog @@@ -1,280 -1,3 +1,286 @@@ +apt (0.8.16~exp6) experimental; urgency=low + ++ [ Christopher Baines ] ++ * enable APT in unpack/configure ordering to handle loops as well ++ as tight dependencies between immediate packages better ++ enabling also the possibility to mark all packages as immediate ++ (at least Closes: #353290, #540227, #559733, #621836, #639290) ++ + [ David Kalnischkies ] + * [abi-break] Support large files in the complete toolset. Indexes of this + size are pretty unlikely for now, but we need it for deb + packages which could become bigger than 4GB now (LP: #815895) + * merged the debian-sid branch + + [ Michael Vogt ] + * bump ABI version + + -- Michael Vogt Wed, 14 Sep 2011 13:26:23 +0200 + +apt (0.8.16~exp5) experimental; urgency=low + + * merged the latest debian-sid fixes + * apt-pkg/makefile: + - install sha256.h compat header + * apt-pkg/pkgcachegen.{cc,h}: + - use ref-to-ptr semantic in NewDepends() to ensure that the + libapt does not segfault if the cache is remapped in between + (LP: #812862) + - fix crash when P.Arch() was used but the cache got remapped + * apt-pkg/acquire-item.{cc,h}: + - do not check for a "Package" tag in optional index targets + like the translations index + * apt-pkg/acquire.cc: + - fix potential divide-by-zero + * methods/mirror.cc: + - include the architecture(s) in the query string as well so + that the server can make better decisions + + -- Michael Vogt Mon, 15 Aug 2011 14:52:54 +0200 + +apt (0.8.16~exp4) experimental; urgency=low + + [ Julian Andres Klode ] + * apt-pkg/pkgcache.h: + - [ABI break] Add pkgCache::Header::CacheFileSize, storing the cache size + * apt-pkg/pkgcachegen.cc: + - Write the file size to the cache + * apt-pkg/pkgcache.cc: + - Check that cache is at least CacheFileSize bytes large (LP: #16467) + + [ Michael Vogt ] + * merged latest fixes from debian-sid + * apt-pkg/cdrom.{cc,h}: + - cleanup old ABI break avoidance hacks + * [ABI break] apt-pkg/acquire-item.{cc,h}: + - cleanup around OptionalIndexTarget and SubIndexTarget + * [ABI break] merged patch from Jonathan Thomas to have a new + RecordField() function in the pkgRecorder parser. Many thanks + Thomas + * [ABI break] merge patch from Jonathan Thomas to speed up the + depcache by caching the install-recommends and install-suggests + values + * apt-pkg/contrib/fileutl.{cc,h}: + - add GetModificationTime() helper + * apt-pkg/pkgcachegen.cc: + - regenerate the cache if the sources.list changes to ensure + that changes in the ordering there will be honored by apt + * apt-pkg/sourcelist.{cc,h}: + - add pkgSourceList::GetLastModifiedTime() helper + + -- Michael Vogt Thu, 28 Jul 2011 16:57:08 +0200 + +apt (0.8.16~exp3) experimental; urgency=low + + [ David Kalnischkies ] + * apt-pkg/pkgcache.h: + - readd All{Foreign,Allowed} as suggested by Julian to + remain strictly API compatible + * apt-pkg/acquire*.{cc,h}: + - try even harder to support really big files in the fetcher by + converting (hopefully) everything to 'long long' (Closes: #632271) + * ftparchive/writer.cc: + - generate all checksums in one run over the file for Release + * cmdline/apt-get.cc: + - add an --assume-no option for testing to say 'no' to everything + * apt-pkg/deb/debmetaindex.cc: + - add trusted=yes option to mark unsigned (local) repository as trusted + based on a patch from Ansgar Burchardt, thanks a lot! (Closes: #596498) + + [ Michael Vogt ] + * merge fixes from the debian/unstable upload + * merge lp:~mvo/apt/sha512-template to get fixes for the + sha1/md5 verifiation (closes: #632520) + + -- Michael Vogt Fri, 15 Jul 2011 09:56:17 +0200 + +apt (0.8.16~exp2) experimental; urgency=low + + [ David Kalnischkies ] + * [ABI-Break] Implement EDSP in libapt-pkg so that all front-ends which + use the internal resolver can now be used also with external + ones as the usage is hidden in between the old API + * provide two edsp solvers in apt-utils: + - 'dump' to quickly output a complete scenario and + - 'apt' to use the internal as an external resolver + * apt-pkg/pkgcache.h: + - clean up mess with the "all" handling in MultiArch to + fix LP: #733741 cleanly for everyone now + * apt-pkg/depcache.cc: + - use a boolean instead of an int for Add/Remove in AddStates + similar to how it works with AddSizes + - let the Mark methods return if their marking was successful + - if a Breaks can't be upgraded, remove it. If it or a Conflict + can't be removed the installation of the breaker fails. + * cmdline/apt-get.cc: + - do not discard the error messages from the resolver and instead + only show the general 'Broken packages' message if nothing else + + [ Stefano Zacchiroli ] + * doc/external-dependency-solver-protocol.txt: + - describe EDSP and the configuration interface around it + + [ Michael Vogt ] + * [ABI-Break] merge lp:~mvo/apt/sha512-template to add support for sha512 + * [ABI-Break] merge lp:~mvo/apt/dpointer to support easier extending + without breaking the ABI + * increase ABI version and update package names + + -- Michael Vogt Wed, 29 Jun 2011 13:57:28 +0200 + +apt (0.8.16~exp1) experimental; urgency=low + + * merged with the debian/unstable upload + + -- Michael Vogt Wed, 29 Jun 2011 12:40:31 +0200 + +apt (0.8.15.7) unstable; urgency=low + + [ David Kalnischkies ] + * apt-pkg/packagemanager.cc, apt-pkg/pkgcache.cc: + - ignore "self"-conflicts for all architectures of a package + instead of just for the architecture of the package look at + in the ordering of installations, too (LP: #802901) + - M-A:same lockstep unpack should operate on installed + packages first (LP: #835625) + * test/* + - reorganize the various testcases and helper we have and + integrate them better into the buildsystem + - run the test/libapt testcases at package build-time + * debian/apt.symbols: + - add the newly added symbols since 0.8.15.3 + * cmdline/apt-get.cc: + - remove the binary caches in 'apt-get clean' as it is the first + thing recommend by many supporters in case of APT segfaults + - remove the caches in 'apt-get update', too, as they will be + invalid in most cases anyway + * apt-pkg/acquire-item.cc: + - if no Release.gpg file is found try to verify with hashes, + but do not fail if a hash can't be found + * apt-pkg/acquire.cc: + - non-existing directories are by definition clean + * cmdline/apt-key: + - if command is 'add' do not error out if the specified + keyring doesn't exist, it will be created by gpg + * apt-pkg/orderlist.cc: + - prefer visiting packages marked for deletion in VisitProvides + if we are operating on a negative dependency so that we can + deal early with the fallout of this remove + * apt-pkg/indexrecords.cc: + - fix Acquire::Max-ValidTime option by interpreting it really + as seconds as specified in the manpage and not as days + - add an Acquire::Min-ValidTime option (Closes: #640122) + * doc/apt.conf.5.xml: + - reword Acquire::Max-ValidTime documentation to make clear + that it doesn't provide the new Min-ValidTime functionality + + -- Michael Vogt Mon, 12 Sep 2011 16:38:46 +0200 + +apt (0.8.15.6) unstable; urgency=low + + [ Michael Vogt ] + * apt-pkg/contrib/fileutl.{cc,h}: + - add GetModificationTime() helper + * apt-pkg/pkgcachegen.cc: + - regenerate the cache if the sources.list changes to ensure + that changes in the ordering there will be honored by apt + * apt-pkg/sourcelist.{cc,h}: + - add pkgSourceList::GetLastModifiedTime() helper + * apt-pkg/pkgcachegen.{cc,h}: + - use ref-to-ptr semantic in NewDepends() to ensure that the + libapt does not segfault if the cache is remapped in between + (LP: #812862) + - fix crash when P.Arch() was used but the cache got remapped + * test/integration/test-hashsum-verification: + - add regression test for hashsum verification + * apt-pkg/acquire-item.cc: + - if no Release.gpg file is found, still load the hashes for + verification (closes: #636314) and add test + + [ David Kalnischkies ] + * lots of cppcheck fixes + + -- Michael Vogt Mon, 15 Aug 2011 09:20:35 +0200 + +apt (0.8.15.5) unstable; urgency=low + + [ David Kalnischkies ] + * apt-pkg/deb/deblistparser.cc: + - do not assume that the last char on a line is a \n (Closes: #633350) + + -- Michael Vogt Thu, 28 Jul 2011 16:49:15 +0200 + +apt (0.8.15.4) unstable; urgency=low + + [ David Miller ] + * apt-pkg/contrib/sha1.cc: + - fix illegally casts of on-stack buffer to a type requiring more + alignment than it has resulting in segfaults on sparc (Closes: #634696) + + [ Michael Vogt ] + * apt-pkg/contrib/cdromutl.cc: + - fix escape problem when looking for the mounted devices + * apt-pkg/contrib/strutl.{h,cc}, test/libapt/strutil_test.cc: + - add new DeEscapeString() similar to DeQuoteString but + unescape character escapes like \0XX and \xXX (plus added + test) + * refresh po/* + + -- Michael Vogt Tue, 26 Jul 2011 12:12:27 +0200 + +apt (0.8.15.3) unstable; urgency=low + + [ Michael Vogt ] + * apt-pkg/acquire-item.cc: + - improve error message for a expired Release file + * apt-pkg/algorithms.cc: + - Hold back packages that would enter "policy-broken" state on upgrade + when doing a "apt-get upgrade" + * cmdline/apt-get.cc: + - fix missing download progress in apt-get download + + [ David Kalnischkies ] + * apt-pkg/pkgcachegen.cc: + - fallback to memory if file is not writeable even if access() + told us the opposite before (e.g. in fakeroot 1.16) (Closes: #630591) + * doc/sources.list.5.xml: + - document available [options] for sources.list entries (Closes: 632441) + * doc/apt.conf.5.xml: + - document APT::Architectures list (Closes: #612102) + * cmdline/apt-get.cc: + - restore all important dependencies for garbage packages (LP: #806274) + - do not require unused partial dirs in 'source' (Closes: #633510) + - buildconflicts effect all architectures + - implement MultiarchCross for build-dep and source (Closes: #632221) + * apt-pkg/init.cc: + - use CndSet in pkgInitConfig (Closes: #629617) + * apt-pkg/depcache.cc: + - change default of APT::AutoRemove::SuggestsImportant to true + * cmdline/apt-key: + - use a tmpfile instead of /etc/apt/secring.gpg (Closes: #632596) + * debian/apt.postinst: + - remove /etc/apt/secring.gpg if it is an empty file + * doc/apt-cache.8.xml: + - apply madison typofix from John Feuerstein, thanks! (Closes: #633455) + * apt-pkg/policy.cc: + - emit an error on unknown APT::Default-Release value (Closes: #407511) + * apt-pkg/aptconfiguration.cc: + - ensure that native architecture is if not specified otherwise the + first architecture in the Architectures vector + * apt-pkg/deb/deblistparser.cc: + - Strip only :any and :native if MultiArch should be stripped as it is + save to ignore them in non-MultiArch contexts but if the dependency + is a specific architecture (and not the native) do not strip + + -- Michael Vogt Mon, 25 Jul 2011 15:04:43 +0200 + +apt (0.8.15.2) unstable; urgency=high + + * fix from David Kalnischkies for the InRelease gpg verification + code (LP: #784473) + + -- Michael Vogt Tue, 12 Jul 2011 11:54:47 +0200 + apt (0.8.15.1) unstable; urgency=low [ David Kalnischkies ] @@@ -407,185 -130,6 +413,185 @@@ apt (0.8.15) unstable; urgency=lo -- Michael Vogt Tue, 28 Jun 2011 18:00:48 +0200 +apt (0.8.15~exp3) experimental; urgency=low + + * debian/control: + - add Breaks: 0.8.15~exp3) for libapt-pkg4.10 and + libapt-inst1.2 (thanks to Jonathan Nieder, closes: #630214) + - use depends for the ${shlibs:Depends} to make the breaks work + + -- Michael Vogt Fri, 17 Jun 2011 21:51:41 +0200 + +apt (0.8.15~exp2) experimental; urgency=low + + * debian/control: + - fix incorrect Replaces (closes: #630204) for libapt-inst1.2 + + -- Michael Vogt Wed, 15 Jun 2011 16:51:14 +0200 + +apt (0.8.15~exp1) experimental; urgency=low + + [ Julian Andres Klode ] + * apt-pkg/depcache.cc: + - Really release action groups only once (Closes: #622744) + - Make purge work again for config-files (LP: #244598) (Closes: #150831) + * apt-pkg/acquire-item.cc: + - Reject files known to be invalid (LP: #346386) (Closes: #627642) + * debian/apt.cron.daily: + - Check power after wait, patch by manuel-soto (LP: #705269) + * debian/control: + - Move ${shlibs:Depends} to Pre-Depends, as we do not want APT + unpacked if a library is too old and thus break upgrades + * doc/apt-key.8.xml: + - Document apt-key net-update (LP: #192810) + + [ Christian Perrier ] + * Galician translation update (Miguel Anxo Bouzada). Closes: #626505 + * Italian translation update (Milo Casagrande). Closes: #627834 + * German documentation translation update (Chris Leick). Closes: #629949 + + [ David Kalnischkies ] + * fix a bunch of cppcheck warnings/errors based on a patch by + Niels Thykier, thanks! (Closes: #622805) + * apt-pkg/depcache.cc: + - really include 'rc' packages in the delete count by fixing a + typo which exists since 1999 in the source… (LP: #761175) + - if critical or-group can't be satisfied, exit directly. + * apt-pkg/acquire-method.cc: + - write directly to stdout instead of creating the message in + memory first before writing to avoid hitting limits + - fix order of CurrentURI and UsedMirror in Status() and Log() + * apt-pkg/orderlist.cc: + - let VisitRProvides report if the calls were successful + * apt-pkg/deb/dpkgpm.cc: + - replace obsolete usleep with nanosleep + * debian/apt{,-utils}.symbols: + - update both experimental symbol-files to reflect 0.8.14 state + * debian/rules: + - remove unused embedded jquery by doxygen from libapt-pkg-doc + * cmdline/apt-mark.cc: + - reimplement apt-mark in c++ + - provide a 'showmanual' command (Closes: #582791) + - provide a 'dpkg --set-selections' wrapper to set/release holds + * cmdline/apt-get.cc: + - deprecate mostly undocumented 'markauto' in favor of 'apt-mark' + * cmdline/apt-cache.cc: + - deprecate mostly undocumented 'showauto' in favor of 'apt-mark' + * apt-pkg/pkgcache.cc: + - really ignore :arch in FindPkg() in non-multiarch environment + * doc/po/de.po: + - undo the translation of the command 'dump' in manpage of apt-config + as report by Burghard Grossmann on debian-l10n-german, thanks! + * apt-pkg/deb/debmetaindex.cc: + - do not download TranslationIndex if no Translation-* will be + downloaded later on anyway (Closes: #624218) + * test/versions.lst: + - disable obscure version number tests with versions dpkg doesn't + allow any more as they don't start with a number + * apt-pkg/acquire-worker.cc: + - print filename in the unmatching size warning (Closes: #623137) + * apt-pkg/acquire-item.cc: + - apply fix for poorly worded 'locate file' error message from + Ben Finney, thanks! (Closes: #623171) + * methods/http.cc: + - add config option to ignore a closed stdin to be able to easily + use the method as a simple standalone downloader + - Location header in redirects should be absolute URI, but some + servers just send an absolute path so still deal with it properly + - dequote URL taken from Location in redirects as we will otherwise + quote an already quoted string in the request later (Closes: #602412) + * apt-pkg/contrib/netrc.cc: + - replace non-posix gnu-extension strdupa with strdup + * apt-pkg/packagemanager.cc: + - ensure for Multi-Arch:same packages that they are unpacked in + lock step even in immediate configuration (Closes: #618288) + + [ Michael Vogt ] + * methods/mirror.cc: + - ignore lines starting with "#" in the mirror file + - ignore non http urls in the mirrors + - append the dist (e.g. sid, wheezy) as a query string when + asking for a suitable mirror + * debian/control: + - add libapt-pkg4.10 and libapt-inst1.2 library packages + + -- Michael Vogt Fri, 10 Jun 2011 15:32:07 +0200 + +apt (0.8.14.2) UNRELEASED; urgency=low + + [ Julian Andres Klode ] + * apt-pkg/depcache.cc: + - Really release action groups only once (Closes: #622744) + - Make purge work again for config-files (LP: #244598) (Closes: #150831) + * debian/apt.cron.daily: + - Check power after wait, patch by manuel-soto (LP: #705269) + * debian/control: + - Move ${shlibs:Depends} to Pre-Depends, as we do not want APT + unpacked if a library is too old and thus break upgrades + * doc/apt-key.8.xml: + - Document apt-key net-update (LP: #192810) + + [ Christian Perrier ] + * Galician translation update (Miguel Anxo Bouzada). Closes: #626505 + + [ David Kalnischkies ] + * fix a bunch of cppcheck warnings/errors based on a patch by + Niels Thykier, thanks! (Closes: #622805) + * apt-pkg/depcache.cc: + - really include 'rc' packages in the delete count by fixing a + typo which exists since 1999 in the source… (LP: #761175) + - if critical or-group can't be satisfied, exit directly. + * apt-pkg/acquire-method.cc: + - write directly to stdout instead of creating the message in + memory first before writing to avoid hitting limits + - fix order of CurrentURI and UsedMirror in Status() and Log() + * apt-pkg/orderlist.cc: + - let VisitRProvides report if the calls were successful + * apt-pkg/deb/dpkgpm.cc: + - replace obsolete usleep with nanosleep + * debian/apt{,-utils}.symbols: + - update both experimental symbol-files to reflect 0.8.14 state + * debian/rules: + - remove unused embedded jquery by doxygen from libapt-pkg-doc + * cmdline/apt-mark.cc: + - reimplement apt-mark in c++ + - provide a 'showmanual' command (Closes: #582791) + - provide a 'dpkg --set-selections' wrapper to set/release holds + * cmdline/apt-get.cc: + - deprecate mostly undocumented 'markauto' in favor of 'apt-mark' + * cmdline/apt-cache.cc: + - deprecate mostly undocumented 'showauto' in favor of 'apt-mark' + * apt-pkg/pkgcache.cc: + - really ignore :arch in FindPkg() in non-multiarch environment + * doc/po/de.po: + - undo the translation of the command 'dump' in manpage of apt-config + as report by Burghard Grossmann on debian-l10n-german, thanks! + * apt-pkg/deb/debmetaindex.cc: + - do not download TranslationIndex if no Translation-* will be + downloaded later on anyway (Closes: #624218) + * test/versions.lst: + - disable obscure version number tests with versions dpkg doesn't + allow any more as they don't start with a number + * apt-pkg/acquire-worker.cc: + - print filename in the unmatching size warning (Closes: #623137) + * apt-pkg/acquire-item.cc: + - apply fix for poorly worded 'locate file' error message from + Ben Finney, thanks! (Closes: #623171) + * methods/http.cc: + - add config option to ignore a closed stdin to be able to easily + use the method as a simple standalone downloader + - Location header in redirects should be absolute URI, but some + servers just send an absolute path so still deal with it properly + - dequote URL taken from Location in redirects as we will otherwise + quote an already quoted string in the request later (Closes: #602412) + * apt-pkg/contrib/netrc.cc: + - replace non-posix gnu-extension strdupa with strdup + * apt-pkg/packagemanager.cc: + - ensure for Multi-Arch:same packages that they are unpacked in + lock step even in immediate configuration (Closes: #618288) + + -- Michael Vogt Mon, 16 May 2011 14:57:52 +0200 + apt (0.8.14.1) unstable; urgency=low * apt-pkg/acquire-item.cc: diff --combined test/integration/test-bug-618288-multiarch-same-lockstep index a05f03df4,7e384e428..7333054cc --- a/test/integration/test-bug-618288-multiarch-same-lockstep +++ b/test/integration/test-bug-618288-multiarch-same-lockstep @@@ -17,16 -17,16 +17,29 @@@ buildsimplenativepackage 'apt2' 'amd64 setupaptarchive --testequal 'Reading package lists... ++# order in switch libsame:{amd64,i386} are unpacked is irrelevant, as both are installed - but we need to do it together ++testequalor2 'Reading package lists... +Building dependency tree... +The following packages will be upgraded: + apt:i386 apt2 libsame libsame:i386 +4 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. +Inst libsame:i386 [1] (2 unstable [i386]) [libsame:amd64 on libsame:i386] [libsame:i386 on libsame:amd64] [libsame:amd64 apt:i386 ] +Inst libsame [1] (2 unstable [amd64]) [apt2:amd64 apt:i386 ] +Conf libsame:i386 (2 unstable [i386]) [apt2:amd64 apt:i386 ] +Conf libsame (2 unstable [amd64]) [apt2:amd64 apt:i386 ] +Inst apt2 [1] (2 unstable [amd64]) [apt:i386 ] +Conf apt2 (2 unstable [amd64]) [apt:i386 ] +Inst apt:i386 [1] (2 unstable [i386]) ++Conf apt:i386 (2 unstable [i386])' 'Reading package lists... + Building dependency tree... + The following packages will be upgraded: + apt:i386 apt2 libsame libsame:i386 + 4 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. + Inst libsame [1] (2 unstable [amd64]) [libsame:amd64 on libsame:i386] [libsame:i386 on libsame:amd64] [libsame:i386 apt2:amd64 ] + Inst libsame:i386 [1] (2 unstable [i386]) [apt2:amd64 apt:i386 ] + Conf libsame:i386 (2 unstable [i386]) [apt2:amd64 apt:i386 ] + Conf libsame (2 unstable [amd64]) [apt2:amd64 apt:i386 ] + Inst apt2 [1] (2 unstable [amd64]) [apt:i386 ] + Conf apt2 (2 unstable [amd64]) [apt:i386 ] + Inst apt:i386 [1] (2 unstable [i386]) Conf apt:i386 (2 unstable [i386])' aptget dist-upgrade -s