From 7546c8da99ade7b6e1bd6aaa9d026f61400214d1 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 11 Jul 2013 23:09:47 +0200 Subject: Add DPkgPM::Progress for terminal install progress --- apt-pkg/deb/dpkgpm.cc | 17 ++++++++++++++++- apt-pkg/deb/dpkgpm.h | 2 ++ 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index fb0473535..3fb80d158 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -620,6 +620,9 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) << ":" << (PackagesDone/float(PackagesTotal)*100.0) << ":" << s << endl; + if(_config->FindB("DPkgPM::Progress", false) == true) + SendTerminalProgress(PackagesDone/float(PackagesTotal)*100.0); + if(OutStatusFd > 0) FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); if (Debug == true) @@ -860,6 +863,18 @@ bool pkgDPkgPM::CloseLog() return true; } /*}}}*/ +// DPkgPM::SendTerminalProgress /*{{{*/ +// --------------------------------------------------------------------- +/* Send progress info to the terminal + */ +void pkgDPkgPM::SendTerminalProgress(float percentage) +{ + // FIXME: use colors too + std::cout << "\r\n" + << "Progress: [" << percentage << "%]" + << "\r\n"; +} + /*}}}*/ /*{{{*/ // This implements a racy version of pselect for those architectures // that don't have a working implementation. @@ -1274,7 +1289,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); } Child = ExecFork(); - + // This is the child if (Child == 0) { diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index c31d56f8e..29901a204 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -84,6 +84,8 @@ class pkgDPkgPM : public pkgPackageManager bool SendPkgsInfo(FILE * const F, unsigned int const &Version); void WriteHistoryTag(std::string const &tag, std::string value); + void SendTerminalProgress(float percentage); + // apport integration void WriteApportReport(const char *pkgpath, const char *errormsg); -- cgit v1.2.3 From b40394c0ff509954c37254b0993a985ea3ff1467 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 6 Aug 2013 09:13:27 +0200 Subject: memset() pkgTagSections data to make coverity happy --- apt-pkg/tagfile.cc | 10 ++++++++++ apt-pkg/tagfile.h | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc index 1c79ee74f..83c1a9a55 100644 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@ -218,6 +218,16 @@ bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long long Offset) return true; } /*}}}*/ +// pkgTagSection::pkgTagSection - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgTagSection::pkgTagSection() + : Section(0), TagCount(0), Stop(0), d(NULL) +{ + memset(&Indexes, 0, sizeof(Indexes)); + memset(&AlphaIndexes, 0, sizeof(AlphaIndexes)); +} + /*}}}*/ // TagSection::Scan - Scan for the end of the header information /*{{{*/ // --------------------------------------------------------------------- /* This looks for the first double new line in the data stream. diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h index 126f4219d..7b496ffd8 100644 --- a/apt-pkg/tagfile.h +++ b/apt-pkg/tagfile.h @@ -84,7 +84,7 @@ class pkgTagSection Stop = this->Stop; }; - pkgTagSection() : Section(0), TagCount(0), Stop(0), d(NULL) {}; + pkgTagSection(); virtual ~pkgTagSection() {}; }; -- cgit v1.2.3 From 70e0c1683e7021a0682b0808b329a3cced3920ac Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 12 Aug 2013 17:24:15 +0200 Subject: some more coverity fixes --- apt-pkg/acquire-item.cc | 2 ++ apt-pkg/contrib/cmndline.cc | 1 + apt-pkg/contrib/strutl.cc | 2 ++ 3 files changed, 5 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 7bcdf285b..f70cabeff 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -984,6 +984,8 @@ void pkgAcqIndex::Done(string Message,unsigned long long Size,string Hash, DestFile += ".decomp"; Desc.URI = decompProg + ":" + FileName; QueueURI(Desc); + + // FIXME: this points to a c++ string that goes out of scope Mode = decompProg.c_str(); } /*}}}*/ diff --git a/apt-pkg/contrib/cmndline.cc b/apt-pkg/contrib/cmndline.cc index 75d02cad4..d77ef4540 100644 --- a/apt-pkg/contrib/cmndline.cc +++ b/apt-pkg/contrib/cmndline.cc @@ -361,6 +361,7 @@ bool CommandLine::DispatchArg(Dispatch *Map,bool NoMatch) void CommandLine::SaveInConfig(unsigned int const &argc, char const * const * const argv) { char cmdline[100 + argc * 50]; + memset(cmdline, 0, sizeof(cmdline)); unsigned int length = 0; bool lastWasOption = false; bool closeQuote = false; diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index df02c3499..b70a62a47 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -943,6 +943,8 @@ bool StrToTime(const string &Val,time_t &Result) Tm.tm_isdst = 0; if (Month[0] != 0) Tm.tm_mon = MonthConv(Month); + else + Tm.tm_mon = 0; // we don't have a month, so pick something Tm.tm_year -= 1900; // Convert to local time and then to GMT -- cgit v1.2.3 From ec4835a14aae3d4995894c44ec4c4801bac0235d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81ngel=20Guzm=C3=A1n=20Maeso?= Date: Wed, 21 Aug 2013 19:38:35 +0200 Subject: apt-pkg:contrib Avoid compiler warning about sign-compare MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The fix avoid the warning "comparison between signed and unsigned integer expressions [-Wsign-compare]"· The index for the loop needs to be unsigned for compare with globbuf.gl_pathc structure member --- apt-pkg/contrib/fileutl.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index dca468c63..47a91c294 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -1777,7 +1777,8 @@ std::vector Glob(std::string const &pattern, int flags) { std::vector result; glob_t globbuf; - int glob_res, i; + int glob_res; + unsigned int i; glob_res = glob(pattern.c_str(), flags, NULL, &globbuf); -- cgit v1.2.3 From 2510eea4a0922b7b6da8099deb70ca87851633ce Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 22 Aug 2013 22:30:20 +0200 Subject: do chdir("/") after chroot() --- apt-pkg/aptconfiguration.cc | 2 +- apt-pkg/tagfile.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index e32e553a4..4f9b84e00 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -392,7 +392,7 @@ std::vector const Configuration::getArchitectures(bool const &Cache dup2(nullfd, STDIN_FILENO); dup2(external[1], STDOUT_FILENO); dup2(nullfd, STDERR_FILENO); - if (chrootDir != "/" && chroot(chrootDir.c_str()) != 0) + if (chrootDir != "/" && chroot(chrootDir.c_str()) != 0 && chdir("/") != 0) _error->WarningE("getArchitecture", "Couldn't chroot into %s for dpkg --print-foreign-architectures", chrootDir.c_str()); execvp(Args[0], (char**) &Args[0]); _error->WarningE("getArchitecture", "Can't detect foreign architectures supported by dpkg!"); diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc index 868adf3d2..b91e868e2 100644 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@ -237,7 +237,7 @@ bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long long Offset) // --------------------------------------------------------------------- /* */ pkgTagSection::pkgTagSection() - : Section(0), TagCount(0), Stop(0), d(NULL) + : Section(0), TagCount(0), d(NULL), Stop(0) { memset(&Indexes, 0, sizeof(Indexes)); memset(&AlphaIndexes, 0, sizeof(AlphaIndexes)); -- cgit v1.2.3 From 51fc6def77edfb1f429a48e5169519e9e05a759b Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 26 Aug 2013 21:09:33 +0200 Subject: set Acquire::PDiffs::FileLimit to 20 to avoid needless huge fetches --- apt-pkg/acquire-item.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 97b2d1e29..da00c9dd5 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -434,7 +434,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) /*{{{*/ if (available_patches.empty() == false) { // patching with too many files is rather slow compared to a fast download - unsigned long const fileLimit = _config->FindI("Acquire::PDiffs::FileLimit", 0); + unsigned long const fileLimit = _config->FindI("Acquire::PDiffs::FileLimit", 20); if (fileLimit != 0 && fileLimit < available_patches.size()) { if (Debug) -- cgit v1.2.3 From 7335eebea6dd43581d4650a8818b06383ab89901 Mon Sep 17 00:00:00 2001 From: Angel Guzman Maeso Date: Tue, 27 Aug 2013 21:29:01 +0200 Subject: replace usage of potential dangerous mktemp with mkstemp Avoid the warning "the use of `mktemp' is dangerous, better use `mkstemp' or `mkdtemp'". It is not strictly necessary to change the usage from a security point of view here, but mktemp is also removed from the standard since POSIX.1-2008. The mkostemp call returns a file descriptor the logic for TemporaryFileName has been changed accordingly to get the same results. The file permissions are corrected by using fchmod() as the default for FileFd is 666 while mkstemp creates files with 600 by default. --- apt-pkg/contrib/fileutl.cc | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 47a91c294..3eeef58cf 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -946,9 +946,6 @@ bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Co if ((Mode & Atomic) == Atomic) { Flags |= Replace; - char *name = strdup((FileName + ".XXXXXX").c_str()); - TemporaryFileName = string(mktemp(name)); - free(name); } else if ((Mode & (Exclusive | Create)) == (Exclusive | Create)) { @@ -974,8 +971,25 @@ bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Co else if_FLAGGED_SET(Atomic, O_EXCL); #undef if_FLAGGED_SET - if (TemporaryFileName.empty() == false) - iFd = open(TemporaryFileName.c_str(), fileflags, Perms); + if ((Mode & Atomic) == Atomic) + { + char *name = strdup((FileName + ".XXXXXX").c_str()); + + if((iFd = mkostemp(name, fileflags)) == -1) + { + free(name); + return FileFdErrno("mkostemp", "Could not create temporary file for %s", FileName.c_str()); + } + + TemporaryFileName = string(name); + + if(fchmod(iFd, Perms) == -1) + { + free(name); + return FileFdErrno("fchmod", "Could not assign permissions to temporary file %s with error %s", FileName.c_str(), strerror(errno)); + } + free(name); + } else iFd = open(FileName.c_str(), fileflags, Perms); -- cgit v1.2.3 From dc545c0bcd252bca491d0c669adddb5d62390a15 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 27 Aug 2013 21:50:22 +0200 Subject: use mkstemp instead of mkostemp in FileFd::Open() FileFd currently supports no fileflags which would make sense to provide via mkostemp, so we can just use mkstemp here which is a standard function compared to glib extension mkostemp. O_CREAT (Create) and O_TRUNC (Empty) are implied by O_EXCL, which is the mode mkstemp uses by default. The file description is opened ReadWrite, but that used to be the default for FileFd in the old times and not a problem as the difference is needed by FileFd to decide in which way the compressor pipeline needs to be created (if any). Git-Dch: Ignore --- apt-pkg/contrib/fileutl.cc | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 3eeef58cf..4806ae3f9 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -968,27 +968,23 @@ bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Co if_FLAGGED_SET(Create, O_CREAT); if_FLAGGED_SET(Empty, O_TRUNC); if_FLAGGED_SET(Exclusive, O_EXCL); - else if_FLAGGED_SET(Atomic, O_EXCL); #undef if_FLAGGED_SET if ((Mode & Atomic) == Atomic) { char *name = strdup((FileName + ".XXXXXX").c_str()); - if((iFd = mkostemp(name, fileflags)) == -1) + if((iFd = mkstemp(name)) == -1) { free(name); return FileFdErrno("mkostemp", "Could not create temporary file for %s", FileName.c_str()); } TemporaryFileName = string(name); - - if(fchmod(iFd, Perms) == -1) - { - free(name); - return FileFdErrno("fchmod", "Could not assign permissions to temporary file %s with error %s", FileName.c_str(), strerror(errno)); - } free(name); + + if(Perms != 600 && fchmod(iFd, Perms) == -1) + return FileFdErrno("fchmod", "Could not change permissions for temporary file %s", TemporaryFileName.c_str()); } else iFd = open(FileName.c_str(), fileflags, Perms); -- cgit v1.2.3 From 98b69f9dd0ced02b01e276041635c7bb7f2484e3 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 31 Aug 2013 17:05:23 +0200 Subject: fix typo (mkostemp->mkstemp) --- apt-pkg/contrib/fileutl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 4806ae3f9..3966eb0ed 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -977,7 +977,7 @@ bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Co if((iFd = mkstemp(name)) == -1) { free(name); - return FileFdErrno("mkostemp", "Could not create temporary file for %s", FileName.c_str()); + return FileFdErrno("mkstemp", "Could not create temporary file for %s", FileName.c_str()); } TemporaryFileName = string(name); -- cgit v1.2.3 From 00f4d9ffa3468e899abf8fbda8db71fc3143b8e5 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 7 Sep 2013 12:19:51 +0200 Subject: implement StringSplit() as we need this to fix the dpkg status-fd output parsing --- apt-pkg/contrib/strutl.cc | 22 ++++++++++++++++++++++ apt-pkg/contrib/strutl.h | 2 ++ 2 files changed, 24 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 0955b69f7..819d50de0 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -1118,6 +1118,28 @@ vector VectorizeString(string const &haystack, char const &split) return exploded; } /*}}}*/ +// StringSplit - like python string.split /*{{{*/ +// --------------------------------------------------------------------- +/* This can be used to split a given string up into a vector of strings + * The seperator is a string + */ +vector StringSplit(string const &s, std::string const &sep) +{ + vector split; + size_t start, pos; + start = pos = 0; + if(sep.size() == 0) + return split; + + do { + pos = s.find(sep, start); + split.push_back(s.substr(start, pos-start)); + if(pos != string::npos) + start = pos+sep.size(); + } while (pos != string::npos); + return split; +} + /*}}}*/ // RegexChoice - Simple regex list/list matcher /*{{{*/ // --------------------------------------------------------------------- /* */ diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index 530896141..c97246c90 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -65,6 +65,8 @@ bool Hex2Num(const std::string &Str,unsigned char *Num,unsigned int Length); bool TokSplitString(char Tok,char *Input,char **List, unsigned long ListMax); std::vector VectorizeString(std::string const &haystack, char const &split) __attrib_const; +// like python string.split +std::vector StringSplit(std::string const &haystack, std::string const &sep) __attrib_const; void ioprintf(std::ostream &out,const char *format,...) __like_printf(2); void strprintf(std::string &out,const char *format,...) __like_printf(2); char *safe_snprintf(char *Buffer,char *End,const char *Format,...) __like_printf(3); -- cgit v1.2.3 From 85bf001994fa59ca979293af3abb89d3486e0afb Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 7 Sep 2013 13:12:50 +0200 Subject: add maxsplit parameter to StringSplit --- apt-pkg/contrib/strutl.cc | 18 +++++++++++++----- apt-pkg/contrib/strutl.h | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 819d50de0..508af8922 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -1123,19 +1123,27 @@ vector VectorizeString(string const &haystack, char const &split) /* This can be used to split a given string up into a vector of strings * The seperator is a string */ -vector StringSplit(string const &s, std::string const &sep) +vector StringSplit(string const &s, std::string const &sep, + unsigned int maxsplit) { vector split; size_t start, pos; - start = pos = 0; + if(sep.size() == 0) return split; - + + start = pos = 0; do { pos = s.find(sep, start); split.push_back(s.substr(start, pos-start)); - if(pos != string::npos) - start = pos+sep.size(); + + // deal with the max-split + if(maxsplit > 0 && split.size() >= maxsplit) + { + split[split.size()-1] = s.substr(start); + break; + } + start = pos+sep.size(); } while (pos != string::npos); return split; } diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index c97246c90..944f91403 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -66,7 +66,7 @@ bool TokSplitString(char Tok,char *Input,char **List, unsigned long ListMax); std::vector VectorizeString(std::string const &haystack, char const &split) __attrib_const; // like python string.split -std::vector StringSplit(std::string const &haystack, std::string const &sep) __attrib_const; +std::vector StringSplit(std::string const &haystack, std::string const &sep, unsigned int maxsplit=0) __attrib_const; void ioprintf(std::ostream &out,const char *format,...) __like_printf(2); void strprintf(std::string &out,const char *format,...) __like_printf(2); char *safe_snprintf(char *Buffer,char *End,const char *Format,...) __like_printf(3); -- cgit v1.2.3 From cd4ee27de851910dd84067c45d487c5460641913 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 7 Sep 2013 13:30:48 +0200 Subject: fix multiarch status-fd progress calculation --- apt-pkg/deb/dpkgpm.cc | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 3c1013761..d935eb07d 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -512,7 +512,8 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) /* dpkg sends strings like this: - 'status: : ' + 'status: : ' + 'status: :: ' errors look like this: 'status: /var/cache/apt/archives/krecipes_0.8.1-0ubuntu1_i386.deb : error : trying to overwrite `/usr/share/doc/kde/HTML/en/krecipes/krectip.png', which is also in package krecipes-data and conffile-prompt like this @@ -527,29 +528,36 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) 'processing: trigproc: trigger' */ - char* list[6]; - // dpkg sends multiline error messages sometimes (see - // #374195 for a example. we should support this by - // either patching dpkg to not send multiline over the - // statusfd or by rewriting the code here to deal with - // it. for now we just ignore it and not crash - TokSplitString(':', line, list, sizeof(list)/sizeof(list[0])); - if( list[0] == NULL || list[1] == NULL || list[2] == NULL) + // we need to split on ": " (note the appended space) as the ':' is + // part of the pkgname:arch information that dpkg sends + // + // A dpkg error message may contain additional ":" (like + // "failed in buffer_write(fd) (10, ret=-1): backend dpkg-deb ..." + // so we need to ensure to not split too much + std::vector list = StringSplit(line, ": ", 3); + if(list.size() != 3) { if (Debug == true) std::clog << "ignoring line: not enough ':'" << std::endl; return; } - const char* const pkg = list[1]; - const char* action = _strstrip(list[2]); + // dpkg does not send always send "pkgname:arch" so we add it here if needed + std::string pkgname = list[1]; + if (pkgname.find(":") == std::string::npos) + { + string const nativeArch = _config->Find("APT::Architecture"); + pkgname = pkgname + ":" + nativeArch; + } + const char* const pkg = pkgname.c_str(); + const char* action = list[2].c_str(); // 'processing' from dpkg looks like // 'processing: action: pkg' - if(strncmp(list[0], "processing", strlen("processing")) == 0) + if(strncmp(list[0].c_str(), "processing", strlen("processing")) == 0) { char s[200]; - const char* const pkg_or_trigger = _strstrip(list[2]); - action = _strstrip( list[1]); + const char* const pkg_or_trigger = list[2].c_str(); + action = list[1].c_str(); const std::pair * const iter = std::find_if(PackageProcessingOpsBegin, PackageProcessingOpsEnd, @@ -578,14 +586,6 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) if(strncmp(action,"error",strlen("error")) == 0) { - // urgs, sometime has ":" in its error string so that we - // end up with the error message split between list[3] - // and list[4], e.g. the message: - // "failed in buffer_write(fd) (10, ret=-1): backend dpkg-deb ..." - // concat them again - if( list[4] != NULL ) - list[3][strlen(list[3])] = ':'; - status << "pmerror:" << list[1] << ":" << (PackagesDone/float(PackagesTotal)*100.0) << ":" << list[3] @@ -595,7 +595,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) if (Debug == true) std::clog << "send: '" << status.str() << "'" << endl; pkgFailures++; - WriteApportReport(list[1], list[3]); + WriteApportReport(list[1].c_str(), list[3].c_str()); return; } else if(strncmp(action,"conffile",strlen("conffile")) == 0) @@ -1035,7 +1035,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) if((*I).Pkg.end() == true) continue; - string const name = (*I).Pkg.Name(); + string const name = (*I).Pkg.FullName(); PackageOpsDone[name] = 0; for(int i=0; (DpkgStatesOpMap[(*I).Op][i]).state != NULL; ++i) { -- cgit v1.2.3 From 9572a54bbc96eb653b3e13260abb183ba7a316f3 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 7 Sep 2013 16:16:49 +0200 Subject: doc update --- apt-pkg/contrib/strutl.cc | 15 +++++++++------ apt-pkg/contrib/strutl.h | 10 ++++++++-- 2 files changed, 17 insertions(+), 8 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 508af8922..fd768f183 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -1118,10 +1118,11 @@ vector VectorizeString(string const &haystack, char const &split) return exploded; } /*}}}*/ -// StringSplit - like python string.split /*{{{*/ +// StringSplit - split a string into a string vector by token /*{{{*/ // --------------------------------------------------------------------- -/* This can be used to split a given string up into a vector of strings - * The seperator is a string +/* This can be used to split a given string up from a given string token + * into a vector of strings. A optional "maxsplit" argument can be used + * to limit the splitting, in this case the */ vector StringSplit(string const &s, std::string const &sep, unsigned int maxsplit) @@ -1129,22 +1130,24 @@ vector StringSplit(string const &s, std::string const &sep, vector split; size_t start, pos; + // no seperator given, this is bogus if(sep.size() == 0) return split; start = pos = 0; - do { + while (pos != string::npos) + { pos = s.find(sep, start); split.push_back(s.substr(start, pos-start)); - // deal with the max-split + // if maxsplit is reached, the remaining string is the last item if(maxsplit > 0 && split.size() >= maxsplit) { split[split.size()-1] = s.substr(start); break; } start = pos+sep.size(); - } while (pos != string::npos); + } return split; } /*}}}*/ diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index 944f91403..080f9f82e 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -62,11 +62,17 @@ bool StrToNum(const char *Str,unsigned long &Res,unsigned Len,unsigned Base = 0) bool StrToNum(const char *Str,unsigned long long &Res,unsigned Len,unsigned Base = 0); bool Base256ToNum(const char *Str,unsigned long &Res,unsigned int Len); bool Hex2Num(const std::string &Str,unsigned char *Num,unsigned int Length); + +// input changing string split bool TokSplitString(char Tok,char *Input,char **List, unsigned long ListMax); + +// split a given string by a char std::vector VectorizeString(std::string const &haystack, char const &split) __attrib_const; -// like python string.split -std::vector StringSplit(std::string const &haystack, std::string const &sep, unsigned int maxsplit=0) __attrib_const; + +// split a given string by a string token +std::vector StringSplit(std::string const &input, std::string const &sep, unsigned int maxsplit=0) __attrib_const; + void ioprintf(std::ostream &out,const char *format,...) __like_printf(2); void strprintf(std::string &out,const char *format,...) __like_printf(2); char *safe_snprintf(char *Buffer,char *End,const char *Format,...) __like_printf(3); -- cgit v1.2.3 From facea693b2078327b59502e663c238c50118e96a Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 18 Sep 2013 17:55:44 +0200 Subject: improve the API for Upgrade() --- apt-pkg/algorithms.cc | 38 ++++++++++++++++++++++++++++++-------- apt-pkg/algorithms.h | 12 ++++++++++-- 2 files changed, 40 insertions(+), 10 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 69d4acd83..68531f3ca 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -422,12 +422,8 @@ bool pkgDistUpgrade(pkgDepCache &Cache) return Fix.Resolve(); } /*}}}*/ -// AllUpgrade - Upgrade as many packages as possible /*{{{*/ -// --------------------------------------------------------------------- -/* Right now the system must be consistent before this can be called. - It also will not change packages marked for install, it only tries - to install packages not marked for install */ -bool pkgAllUpgrade(pkgDepCache &Cache) +// AllUpgradeNoNewPackages - Upgrade but no removals or new pkgs /*{{{*/ +bool pkgAllUpgradeNoNewPackages(pkgDepCache &Cache) { std::string const solver = _config->Find("APT::Solver", "internal"); if (solver != "internal") { @@ -459,13 +455,13 @@ bool pkgAllUpgrade(pkgDepCache &Cache) return Fix.ResolveByKeep(); } /*}}}*/ -// AllUpgradeNoDelete - Upgrade without removing packages /*{{{*/ +// AllUpgradeWithNewInstalls - Upgrade + install new packages as needed /*{{{*/ // --------------------------------------------------------------------- /* Right now the system must be consistent before this can be called. * Upgrade as much as possible without deleting anything (useful for * stable systems) */ -bool pkgAllUpgradeNoDelete(pkgDepCache &Cache) +bool pkgAllUpgradeWithNewPackages(pkgDepCache &Cache) { pkgDepCache::ActionGroup group(Cache); @@ -502,6 +498,16 @@ bool pkgAllUpgradeNoDelete(pkgDepCache &Cache) return Fix.ResolveByKeep(); } /*}}}*/ +// AllUpgrade - Upgrade as many packages as possible /*{{{*/ +// --------------------------------------------------------------------- +/* Right now the system must be consistent before this can be called. + It also will not change packages marked for install, it only tries + to install packages not marked for install */ +bool pkgAllUpgrade(pkgDepCache &Cache) +{ + return pkgAllUpgradeNoNewPackages(Cache); +} + /*}}}*/ // MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/ // --------------------------------------------------------------------- /* This simply goes over the entire set of packages and tries to keep @@ -547,6 +553,22 @@ bool pkgMinimizeUpgrade(pkgDepCache &Cache) return true; } /*}}}*/ +// APT::Upgrade::Upgrade - Upgrade using a specific strategy /*{{{*/ +bool APT::Upgrade::Upgrade(pkgDepCache &Cache, APT::Upgrade::UpgradeMode mode) +{ + switch(mode) { + case APT::Upgrade::NO_INSTALL_OR_REMOVE: + return pkgAllUpgradeNoNewPackages(Cache); + case APT::Upgrade::ALLOW_NEW_INSTALLS: + return pkgAllUpgradeWithNewPackages(Cache); + case APT::Upgrade::ALLOW_REMOVAL_AND_NEW_INSTALLS: + return pkgDistUpgrade(Cache); + default: + _error->Error("pkgAllUpgrade called with unknwon mode %i", mode); + } + return false; +} + /*}}}*/ // ProblemResolver::pkgProblemResolver - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h index a499db8ba..9ff84e3ff 100644 --- a/apt-pkg/algorithms.h +++ b/apt-pkg/algorithms.h @@ -45,6 +45,15 @@ using std::ostream; class pkgAcquireStatus; +namespace APT { + namespace Upgrade { + enum UpgradeMode {NO_INSTALL_OR_REMOVE, + ALLOW_NEW_INSTALLS, + ALLOW_REMOVAL_AND_NEW_INSTALLS}; + bool Upgrade(pkgDepCache &Cache, UpgradeMode mode); + } +} + class pkgSimulate : public pkgPackageManager /*{{{*/ { protected: @@ -85,6 +94,7 @@ private: /*}}}*/ class pkgProblemResolver /*{{{*/ { + private: /** \brief dpointer placeholder (for later in case we need it) */ void *d; @@ -146,8 +156,6 @@ bool pkgFixBroken(pkgDepCache &Cache); bool pkgAllUpgrade(pkgDepCache &Cache); -bool pkgAllUpgradeNoDelete(pkgDepCache &Cache); - bool pkgMinimizeUpgrade(pkgDepCache &Cache); void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List); -- cgit v1.2.3 From 5985c230c8ac85fe2b2eb504b798377843bdc7cd Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 20 Sep 2013 13:34:22 +0200 Subject: do not trust FileFd::Eof() in pkgTagFile::Fill() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Eof check was added (by me of course) in 0aae6d14390193e25ab6d0fd49295bd7b131954f as part of a fix up ~a month ago (at DebConf). The idea was not that bad, but doesn't make that much sense either as this bit is set by the FileFd based on Actual as well, so this is basically doing the same check again – with the difference that the HitEof bit can still linger from a previous Read we did at the end of the file, but have seek'd away from it now. Combined with the length of entries, entry order and other not that easily controllable conditions you can be 'lucky' enough to hit this problem in a way which even visible (truncating of other fields might not be visible easily, like 'Tags' and others). Closes: 723705 Thanks: Cyril Brulebois --- apt-pkg/tagfile.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc index b91e868e2..e0802e3d5 100644 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@ -164,7 +164,7 @@ bool pkgTagFile::Fill() unsigned long long const dataSize = d->Size - ((d->End - d->Buffer) + 1); if (d->Fd.Read(d->End, dataSize, &Actual) == false) return false; - if (Actual != dataSize || d->Fd.Eof() == true) + if (Actual != dataSize) d->Done = true; d->End += Actual; } -- cgit v1.2.3 From b4140ecf132d15adf740f23330054b6788d4f9a6 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 21 Sep 2013 14:23:02 +0200 Subject: don't strip :any from dependencies in single-arch The parser goes a bit to far by stripping :any from dependencies in a single architecture environment. the flag "Multi-Arch: allowed" doesn't care any architecture restrictions in that case (as in single arch everything is native), but it still limits the possible versions statisfying the dependency so stripping :any over-simplifies in upgrade situations from "Multi-Arch: none" to "Multi-Arch: allowed". Closes: 723586 --- apt-pkg/deb/deblistparser.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 87aab6ee2..68d544e1f 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -635,7 +635,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator &Ver, string Version; unsigned int Op; - Start = ParseDepends(Start,Stop,Package,Version,Op,false,!MultiArchEnabled); + Start = ParseDepends(Start, Stop, Package, Version, Op, false, false); if (Start == 0) return _error->Error("Problem parsing dependency %s",Tag); size_t const found = Package.rfind(':'); @@ -717,9 +717,7 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver) } } - if (MultiArchEnabled == false) - return true; - else if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed) + if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed) { string const Package = string(Ver.ParentPkg().Name()).append(":").append("any"); return NewProvidesAllArch(Ver, Package, Ver.VerStr()); -- cgit v1.2.3 From 6c34cccad778bd8db0ce03b7596cbef03afa9688 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 26 Sep 2013 13:32:49 +0200 Subject: pkg from only trusted sources keeps being trusted --allow-unauthenticated switches the download to a pre-0.6 system in which a package can come from any source, rather than that trusted packages can only come from trusted sources. To allow this the flag used to set all packages as untrusted, which is a bit much, so we check now if the package can be acquired via an untrusted source and only if this is the case set it as untrusted. As APT nowadays supports setting sources as trusted via a flag in the sources.list this mode shouldn't be used that much anymore though. [Note that this is not the patch from the BTS] Closes: 617690 --- apt-pkg/acquire-item.cc | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 97b2d1e29..222b78671 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -1719,27 +1719,34 @@ pkgAcqArchive::pkgAcqArchive(pkgAcquire *Owner,pkgSourceList *Sources, } // check if we have one trusted source for the package. if so, switch - // to "TrustedOnly" mode + // to "TrustedOnly" mode - but only if not in AllowUnauthenticated mode + bool const allowUnauth = _config->FindB("APT::Get::AllowUnauthenticated", false); + bool const debugAuth = _config->FindB("Debug::pkgAcquire::Auth", false); + bool seenUntrusted = false; for (pkgCache::VerFileIterator i = Version.FileList(); i.end() == false; ++i) { pkgIndexFile *Index; if (Sources->FindIndex(i.File(),Index) == false) continue; - if (_config->FindB("Debug::pkgAcquire::Auth", false)) - { + + if (debugAuth == true) std::cerr << "Checking index: " << Index->Describe() - << "(Trusted=" << Index->IsTrusted() << ")\n"; - } - if (Index->IsTrusted()) { + << "(Trusted=" << Index->IsTrusted() << ")" << std::endl; + + if (Index->IsTrusted() == true) + { Trusted = true; - break; + if (allowUnauth == false) + break; } + else + seenUntrusted = true; } // "allow-unauthenticated" restores apts old fetching behaviour // that means that e.g. unauthenticated file:// uris are higher // priority than authenticated http:// uris - if (_config->FindB("APT::Get::AllowUnauthenticated",false) == true) + if (allowUnauth == true && seenUntrusted == true) Trusted = false; // Select a source -- cgit v1.2.3 From 8fa042ca39dcb39d544f015f4a924c5dbc10ad2c Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 30 Sep 2013 18:51:40 +0200 Subject: don't consider holds for autoremoval MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can't remove packages which are held back by the user with a hold, so marking them (or its dependencies) as garbage will lead our autoremover into madness – and given that the package is important enough that the user has held it back it can't be garbage (at least at the moment), so even if a front-end wants to use the info just for information display its a good idea to not consider it garbage for them. Closes: 724995 --- apt-pkg/depcache.cc | 7 ++++--- apt-pkg/depcache.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 978a893f7..a06789cdf 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -896,6 +896,7 @@ char const* PrintMode(char const mode) case pkgDepCache::ModeInstall: return "Install"; case pkgDepCache::ModeKeep: return "Keep"; case pkgDepCache::ModeDelete: return "Delete"; + case pkgDepCache::ModeGarbage: return "Garbage"; default: return "UNKNOWN"; } } @@ -1726,8 +1727,6 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc) follow_recommends = MarkFollowsRecommends(); follow_suggests = MarkFollowsSuggests(); - - // do the mark part, this is the core bit of the algorithm for(PkgIterator p = PkgBegin(); !p.end(); ++p) { @@ -1738,7 +1737,9 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc) // be nice even then a required package violates the policy (#583517) // and do the full mark process also for required packages (p.CurrentVer().end() != true && - p.CurrentVer()->Priority == pkgCache::State::Required)) + p.CurrentVer()->Priority == pkgCache::State::Required) || + // packages which can't be changed (like holds) can't be garbage + (IsModeChangeOk(ModeGarbage, p, 0, false) == false)) { // the package is installed (and set to keep) if(PkgState[p->ID].Keep() && !p.CurrentVer().end()) diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index d9c95349b..61c9aa559 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -128,7 +128,7 @@ class pkgDepCache : protected pkgCache::Namespace enum InternalFlags {AutoKept = (1 << 0), Purge = (1 << 1), ReInstall = (1 << 2), Protected = (1 << 3)}; enum VersionTypes {NowVersion, InstallVersion, CandidateVersion}; - enum ModeList {ModeDelete = 0, ModeKeep = 1, ModeInstall = 2}; + enum ModeList {ModeDelete = 0, ModeKeep = 1, ModeInstall = 2, ModeGarbage = 3}; /** \brief Represents an active action group. * -- cgit v1.2.3 From 41053d721ce7f81652d7e873067376b94f9a060d Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 1 Oct 2013 12:03:37 +0200 Subject: improve documentation for StringSplit() --- apt-pkg/contrib/strutl.cc | 6 ++---- apt-pkg/contrib/strutl.h | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index fd768f183..96c6d2f35 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -1120,11 +1120,9 @@ vector VectorizeString(string const &haystack, char const &split) /*}}}*/ // StringSplit - split a string into a string vector by token /*{{{*/ // --------------------------------------------------------------------- -/* This can be used to split a given string up from a given string token - * into a vector of strings. A optional "maxsplit" argument can be used - * to limit the splitting, in this case the +/* See header for details. */ -vector StringSplit(string const &s, std::string const &sep, +vector StringSplit(std::string const &s, std::string const &sep, unsigned int maxsplit) { vector split; diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index 080f9f82e..eb47287a4 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -70,8 +70,23 @@ bool TokSplitString(char Tok,char *Input,char **List, // split a given string by a char std::vector VectorizeString(std::string const &haystack, char const &split) __attrib_const; -// split a given string by a string token -std::vector StringSplit(std::string const &input, std::string const &sep, unsigned int maxsplit=0) __attrib_const; +/* \brief Return a vector of strings from string "input" where "sep" + * is used as the delimiter string. + * + * \param input The input string. + * + * \param sep The seperator to use. + * + * \param maxsplit (optional) The maximum amount of splitting that + * should be done . + * + * The optional "maxsplit" argument can be used to limit the splitting, + * if used the string is only split on maxsplit places and the last + * item in the vector contains the remainder string. + */ +std::vector StringSplit(std::string const &input, + std::string const &sep, + unsigned int maxsplit=0) __attrib_const; void ioprintf(std::ostream &out,const char *format,...) __like_printf(2); void strprintf(std::string &out,const char *format,...) __like_printf(2); -- cgit v1.2.3 From 2ddab3fb958518acbd26685eeeb7755106b721a3 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 1 Oct 2013 12:38:03 +0200 Subject: change maxsplit default from "0" to maxint --- apt-pkg/contrib/strutl.cc | 2 +- apt-pkg/contrib/strutl.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 96c6d2f35..77e48962c 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -1139,7 +1139,7 @@ vector StringSplit(std::string const &s, std::string const &sep, split.push_back(s.substr(start, pos-start)); // if maxsplit is reached, the remaining string is the last item - if(maxsplit > 0 && split.size() >= maxsplit) + if(split.size() >= maxsplit) { split[split.size()-1] = s.substr(start); break; diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index eb47287a4..b42e06491 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -17,7 +17,7 @@ #define STRUTL_H - +#include #include #include #include @@ -86,7 +86,7 @@ std::vector VectorizeString(std::string const &haystack, char const */ std::vector StringSplit(std::string const &input, std::string const &sep, - unsigned int maxsplit=0) __attrib_const; + unsigned int maxsplit=std::numeric_limits::max()) __attrib_const; void ioprintf(std::ostream &out,const char *format,...) __like_printf(2); void strprintf(std::string &out,const char *format,...) __like_printf(2); -- cgit v1.2.3 From a38e023c9d5a237ccae1755966adc7c0bbdb9d7e Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 2 Oct 2013 10:15:28 +0200 Subject: make dpkg progress slightly nicer --- apt-pkg/deb/dpkgpm.cc | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index d935eb07d..a5097a04f 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -52,7 +53,8 @@ class pkgDPkgPMPrivate { public: pkgDPkgPMPrivate() : stdin_is_dev_null(false), dpkgbuf_pos(0), - term_out(NULL), history_out(NULL) + term_out(NULL), history_out(NULL), + last_reported_progress(0.0) { dpkgbuf[0] = '\0'; } @@ -63,6 +65,8 @@ public: FILE *term_out; FILE *history_out; string dpkg_error; + + float last_reported_progress; }; namespace @@ -883,10 +887,16 @@ bool pkgDPkgPM::CloseLog() */ void pkgDPkgPM::SendTerminalProgress(float percentage) { + int reporting_steps = _config->FindI("DpkgPM::Reporting-Steps", 1); + + if(percentage < (d->last_reported_progress + reporting_steps)) + return; + // FIXME: use colors too std::cout << "\r\n" - << "Progress: [" << percentage << "%]" + << "Progress: [" << std::setw(3) << int(percentage) << "%]" << "\r\n"; + d->last_reported_progress = percentage; } /*}}}*/ /*{{{*/ @@ -1444,7 +1454,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) tcsetattr(0, TCSAFLUSH, &tt); close(master); } - + // Check for an error code. if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0) { @@ -1474,6 +1484,10 @@ bool pkgDPkgPM::Go(int OutStatusFd) } } CloseLog(); + + // dpkg is done at this point + if(_config->FindB("DPkgPM::Progress", false) == true) + SendTerminalProgress(100); if (pkgPackageManager::SigINTStop) _error->Warning(_("Operation was interrupted before it could finish")); -- cgit v1.2.3 From 3c8030a4977536e9d3a1954adc68082ae1c6d5a2 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 3 Oct 2013 01:12:18 +0200 Subject: refactor onError relabeling of DestFile as '.FAILED' This helps ensure three things: - each error is reported via ReportMirrorFailure - if DestFile doesn't exist, do not attempt rename - renames happen for every error The last one wasn't the case for Size mismatches, which isn't nice, but not a exploitable problem per-se as the file isn't picked up and remains in partial/ where the following download-try will at most take it for a partial request which fails the hashsum verification later on Git-Dch: Ignore --- apt-pkg/acquire-item.cc | 75 ++++++++++++++++++++++++++++--------------------- apt-pkg/acquire-item.h | 19 +++++++++++-- 2 files changed, 60 insertions(+), 34 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 222b78671..fcc7c7404 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -143,6 +143,32 @@ void pkgAcquire::Item::Rename(string From,string To) } } /*}}}*/ +bool pkgAcquire::Item::RenameOnError(pkgAcquire::Item::RenameOnErrorState const error)/*{{{*/ +{ + if(FileExists(DestFile)) + Rename(DestFile, DestFile + ".FAILED"); + + switch (error) + { + case HashSumMismatch: + ErrorText = _("Hash Sum mismatch"); + Status = StatAuthError; + ReportMirrorFailure("HashChecksumFailure"); + break; + case SizeMismatch: + ErrorText = _("Size mismatch"); + Status = StatAuthError; + ReportMirrorFailure("SizeFailure"); + break; + case InvalidFormat: + ErrorText = _("Invalid file format"); + Status = StatError; + // do not report as usually its not the mirrors fault, but Portal/Proxy + break; + } + return false; +} + /*}}}*/ // Acquire::Item::ReportMirrorFailure /*{{{*/ // --------------------------------------------------------------------- void pkgAcquire::Item::ReportMirrorFailure(string FailCode) @@ -595,9 +621,7 @@ void pkgAcqIndexDiffs::Finish(bool allDone) if(!ExpectedHash.empty() && !ExpectedHash.VerifyFile(DestFile)) { - Status = StatAuthError; - ErrorText = _("MD5Sum mismatch"); - Rename(DestFile,DestFile + ".FAILED"); + RenameOnError(HashSumMismatch); Dequeue(); return; } @@ -866,10 +890,7 @@ void pkgAcqIndex::Done(string Message,unsigned long long Size,string Hash, if (!ExpectedHash.empty() && ExpectedHash.toStr() != Hash) { - Status = StatAuthError; - ErrorText = _("Hash Sum mismatch"); - Rename(DestFile,DestFile + ".FAILED"); - ReportMirrorFailure("HashChecksumFailure"); + RenameOnError(HashSumMismatch); return; } @@ -878,22 +899,18 @@ void pkgAcqIndex::Done(string Message,unsigned long long Size,string Hash, if (Verify == true) { FileFd fd(DestFile, FileFd::ReadOnly); - pkgTagSection sec; - pkgTagFile tag(&fd); - - // Only test for correctness if the file is not empty (empty is ok) - if (fd.Size() > 0) { - if (_error->PendingError() || !tag.Step(sec)) { - Status = StatError; - _error->DumpErrors(); - Rename(DestFile,DestFile + ".FAILED"); - return; - } else if (!sec.Exists("Package")) { - Status = StatError; - ErrorText = ("Encountered a section with no Package: header"); - Rename(DestFile,DestFile + ".FAILED"); - return; - } + // Only test for correctness if the file is not empty (empty is ok) + if (fd.FileSize() > 0) + { + pkgTagSection sec; + pkgTagFile tag(&fd); + + // all our current indexes have a field 'Package' in each section + if (_error->PendingError() == true || tag.Step(sec) == false || sec.Exists("Package") == false) + { + RenameOnError(InvalidFormat); + return; + } } } @@ -1907,18 +1924,14 @@ void pkgAcqArchive::Done(string Message,unsigned long long Size,string CalcHash, // Check the size if (Size != Version->Size) { - Status = StatError; - ErrorText = _("Size mismatch"); + RenameOnError(SizeMismatch); return; } // Check the hash if(ExpectedHash.toStr() != CalcHash) { - Status = StatError; - ErrorText = _("Hash Sum mismatch"); - if(FileExists(DestFile)) - Rename(DestFile,DestFile + ".FAILED"); + RenameOnError(HashSumMismatch); return; } @@ -2058,9 +2071,7 @@ void pkgAcqFile::Done(string Message,unsigned long long Size,string CalcHash, // Check the hash if(!ExpectedHash.empty() && ExpectedHash.toStr() != CalcHash) { - Status = StatError; - ErrorText = _("Hash Sum mismatch"); - Rename(DestFile,DestFile + ".FAILED"); + RenameOnError(HashSumMismatch); return; } diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h index 10c855e63..6b4f73708 100644 --- a/apt-pkg/acquire-item.h +++ b/apt-pkg/acquire-item.h @@ -83,7 +83,7 @@ class pkgAcquire::Item : public WeakPointable * overwritten. */ void Rename(std::string From,std::string To); - + public: /** \brief The current status of this item. */ @@ -281,6 +281,21 @@ class pkgAcquire::Item : public WeakPointable * pkgAcquire::Remove. */ virtual ~Item(); + + protected: + + enum RenameOnErrorState { + HashSumMismatch, + SizeMismatch, + InvalidFormat + }; + + /** \brief Rename failed file and set error + * + * \param state respresenting the error we encountered + * \param errorMsg a message describing the error + */ + bool RenameOnError(RenameOnErrorState const state); }; /*}}}*/ /** \brief Information about an index patch (aka diff). */ /*{{{*/ @@ -982,7 +997,7 @@ class pkgAcqArchive : public pkgAcquire::Item * * \param Version The package version to download. * - * \param StoreFilename A location in which the actual filename of + * \param[out] StoreFilename A location in which the actual filename of * the package should be stored. It will be set to a guessed * basename in the constructor, and filled in with a fully * qualified filename once the download finishes. -- cgit v1.2.3 From d57f6084aaa3972073114973d149ea2291b36682 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 3 Oct 2013 15:11:21 +0200 Subject: use pkgAcqArchive in 'download' for proper errors With a bit of trickery we can reuse the usual infrastructure we have in place to acquire deb files for the 'download' operation as well, which gains us authentification check & display, error messages, correct filenames and "downloads" from the root-owned archives. --- apt-pkg/acquire-item.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index fcc7c7404..04505b35a 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -1768,9 +1768,8 @@ pkgAcqArchive::pkgAcqArchive(pkgAcquire *Owner,pkgSourceList *Sources, // Select a source if (QueueNext() == false && _error->PendingError() == false) - _error->Error(_("I wasn't able to locate a file for the %s package. " - "This might mean you need to manually fix this package."), - Version.ParentPkg().Name()); + _error->Error(_("Can't find a source to download version '%s' of '%s'"), + Version.VerStr(), Version.ParentPkg().FullName(false).c_str()); } /*}}}*/ // AcqArchive::QueueNext - Queue the next file source /*{{{*/ -- cgit v1.2.3 From 342df712331004aa4907c9dbdf4b7728d087efb0 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 3 Oct 2013 21:34:52 +0200 Subject: fix lzma-support detection via xz binary Clear() only clears a config option, not removing it and an empty setting still exists. Hence we set the option instead to the xz path so that the later existance check can find a binary for the test --- apt-pkg/aptconfiguration.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index 4f9b84e00..115d11616 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -453,7 +453,7 @@ void Configuration::setDefaultConfigurationForCompressors() { _config->CndSet("Dir::Bin::bzip2", "/bin/bzip2"); _config->CndSet("Dir::Bin::xz", "/usr/bin/xz"); if (FileExists(_config->FindFile("Dir::Bin::xz")) == true) { - _config->Clear("Dir::Bin::lzma"); + _config->Set("Dir::Bin::lzma", _config->FindFile("Dir::Bin::xz")); _config->Set("APT::Compressor::lzma::Binary", "xz"); if (_config->Exists("APT::Compressor::lzma::CompressArg") == false) { _config->Set("APT::Compressor::lzma::CompressArg::", "--format=lzma"); -- cgit v1.2.3 From 5ca0cf51194422fb0f094bbf5e61e9f5eb57f013 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 5 Oct 2013 11:54:08 +0200 Subject: cleanup upgrade API some more (thanks for the feedback from David) --- apt-pkg/algorithms.cc | 25 +++++++++++++++---------- apt-pkg/algorithms.h | 10 ++++++---- 2 files changed, 21 insertions(+), 14 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 68531f3ca..b015ed20e 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -554,18 +554,23 @@ bool pkgMinimizeUpgrade(pkgDepCache &Cache) } /*}}}*/ // APT::Upgrade::Upgrade - Upgrade using a specific strategy /*{{{*/ -bool APT::Upgrade::Upgrade(pkgDepCache &Cache, APT::Upgrade::UpgradeMode mode) +bool APT::Upgrade::Upgrade(pkgDepCache &Cache, int mode) { - switch(mode) { - case APT::Upgrade::NO_INSTALL_OR_REMOVE: - return pkgAllUpgradeNoNewPackages(Cache); - case APT::Upgrade::ALLOW_NEW_INSTALLS: - return pkgAllUpgradeWithNewPackages(Cache); - case APT::Upgrade::ALLOW_REMOVAL_AND_NEW_INSTALLS: - return pkgDistUpgrade(Cache); - default: - _error->Error("pkgAllUpgrade called with unknwon mode %i", mode); + if (mode == 0) + { + return pkgDistUpgrade(Cache); + } + else if ((mode & ~FORBID_REMOVE_PACKAGES) == 0) + { + return pkgAllUpgradeWithNewPackages(Cache); + } + else if ((mode & ~(FORBID_REMOVE_PACKAGES|FORBID_NEW_INSTALL_PACKAGES)) == 0) + { + return pkgAllUpgradeNoNewPackages(Cache); } + else + _error->Error("pkgAllUpgrade called with unsupported mode %i", mode); + return false; } /*}}}*/ diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h index 9ff84e3ff..d0de72462 100644 --- a/apt-pkg/algorithms.h +++ b/apt-pkg/algorithms.h @@ -47,10 +47,12 @@ class pkgAcquireStatus; namespace APT { namespace Upgrade { - enum UpgradeMode {NO_INSTALL_OR_REMOVE, - ALLOW_NEW_INSTALLS, - ALLOW_REMOVAL_AND_NEW_INSTALLS}; - bool Upgrade(pkgDepCache &Cache, UpgradeMode mode); + // FIXME: make this "enum class UpgradeMode {" once we enable c++11 + enum UpgradeMode { + FORBID_REMOVE_PACKAGES = 1, + FORBID_NEW_INSTALL_PACKAGES = 2, + }; + bool Upgrade(pkgDepCache &Cache, int UpgradeMode); } } -- cgit v1.2.3 From 82e369c4b93b5b81db7988ab377a3c5bd388268e Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 5 Oct 2013 12:15:03 +0200 Subject: * move upgrade releated code into upgrade.{cc,h} The upgrade releated code is moved into upgrade.{cc,h} and all pkg*Upgrade* prototypes are included in algorihms.h to avoid breaking API (unless build with APT_9_CLEANER_HEADERS). --- apt-pkg/algorithms.cc | 238 --------------------------------------------- apt-pkg/algorithms.h | 20 +--- apt-pkg/makefile | 5 +- apt-pkg/upgrade.cc | 263 ++++++++++++++++++++++++++++++++++++++++++++++++++ apt-pkg/upgrade.h | 29 ++++++ 5 files changed, 300 insertions(+), 255 deletions(-) create mode 100644 apt-pkg/upgrade.cc create mode 100644 apt-pkg/upgrade.h (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index b015ed20e..22701f8a6 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -336,244 +336,6 @@ bool pkgFixBroken(pkgDepCache &Cache) return Fix.Resolve(true); } /*}}}*/ -// DistUpgrade - Distribution upgrade /*{{{*/ -// --------------------------------------------------------------------- -/* This autoinstalls every package and then force installs every - pre-existing package. This creates the initial set of conditions which - most likely contain problems because too many things were installed. - - The problem resolver is used to resolve the problems. - */ -bool pkgDistUpgrade(pkgDepCache &Cache) -{ - std::string const solver = _config->Find("APT::Solver", "internal"); - if (solver != "internal") { - OpTextProgress Prog(*_config); - return EDSP::ResolveExternal(solver.c_str(), Cache, false, true, false, &Prog); - } - - pkgDepCache::ActionGroup group(Cache); - - /* Upgrade all installed packages first without autoinst to help the resolver - in versioned or-groups to upgrade the old solver instead of installing - a new one (if the old solver is not the first one [anymore]) */ - for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) - if (I->CurrentVer != 0) - Cache.MarkInstall(I, false, 0, false); - - /* Auto upgrade all installed packages, this provides the basis - for the installation */ - for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) - if (I->CurrentVer != 0) - Cache.MarkInstall(I, true, 0, false); - - /* Now, install each essential package which is not installed - (and not provided by another package in the same name group) */ - std::string essential = _config->Find("pkgCacheGen::Essential", "all"); - if (essential == "all") - { - for (pkgCache::GrpIterator G = Cache.GrpBegin(); G.end() == false; ++G) - { - bool isEssential = false; - bool instEssential = false; - for (pkgCache::PkgIterator P = G.PackageList(); P.end() == false; P = G.NextPkg(P)) - { - if ((P->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential) - continue; - isEssential = true; - if (Cache[P].Install() == true) - { - instEssential = true; - break; - } - } - if (isEssential == false || instEssential == true) - continue; - pkgCache::PkgIterator P = G.FindPreferredPkg(); - Cache.MarkInstall(P, true, 0, false); - } - } - else if (essential != "none") - for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) - if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) - Cache.MarkInstall(I, true, 0, false); - - /* We do it again over all previously installed packages to force - conflict resolution on them all. */ - for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) - if (I->CurrentVer != 0) - Cache.MarkInstall(I, false, 0, false); - - pkgProblemResolver Fix(&Cache); - - // Hold back held packages. - if (_config->FindB("APT::Ignore-Hold",false) == false) - { - for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) - { - if (I->SelectedState == pkgCache::State::Hold) - { - Fix.Protect(I); - Cache.MarkKeep(I, false, false); - } - } - } - - return Fix.Resolve(); -} - /*}}}*/ -// AllUpgradeNoNewPackages - Upgrade but no removals or new pkgs /*{{{*/ -bool pkgAllUpgradeNoNewPackages(pkgDepCache &Cache) -{ - std::string const solver = _config->Find("APT::Solver", "internal"); - if (solver != "internal") { - OpTextProgress Prog(*_config); - return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, &Prog); - } - - pkgDepCache::ActionGroup group(Cache); - - pkgProblemResolver Fix(&Cache); - - if (Cache.BrokenCount() != 0) - return false; - - // Upgrade all installed packages - for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) - { - if (Cache[I].Install() == true) - Fix.Protect(I); - - if (_config->FindB("APT::Ignore-Hold",false) == false) - if (I->SelectedState == pkgCache::State::Hold) - continue; - - if (I->CurrentVer != 0 && Cache[I].InstallVer != 0) - Cache.MarkInstall(I, false, 0, false); - } - - return Fix.ResolveByKeep(); -} - /*}}}*/ -// AllUpgradeWithNewInstalls - Upgrade + install new packages as needed /*{{{*/ -// --------------------------------------------------------------------- -/* Right now the system must be consistent before this can be called. - * Upgrade as much as possible without deleting anything (useful for - * stable systems) - */ -bool pkgAllUpgradeWithNewPackages(pkgDepCache &Cache) -{ - pkgDepCache::ActionGroup group(Cache); - - pkgProblemResolver Fix(&Cache); - - if (Cache.BrokenCount() != 0) - return false; - - // provide the initial set of stuff we want to upgrade by marking - // all upgradable packages for upgrade - for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) - { - if (I->CurrentVer != 0 && Cache[I].InstallVer != 0) - { - if (_config->FindB("APT::Ignore-Hold",false) == false) - if (I->SelectedState == pkgCache::State::Hold) - continue; - - Cache.MarkInstall(I, false, 0, false); - } - } - - // then let auto-install loose - for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) - if (Cache[I].Install()) - Cache.MarkInstall(I, true, 0, false); - - // ... but it may remove stuff, we we need to clean up afterwards again - for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) - if (Cache[I].Delete() == true) - Cache.MarkKeep(I, false, false); - - // resolve remaining issues via keep - return Fix.ResolveByKeep(); -} - /*}}}*/ -// AllUpgrade - Upgrade as many packages as possible /*{{{*/ -// --------------------------------------------------------------------- -/* Right now the system must be consistent before this can be called. - It also will not change packages marked for install, it only tries - to install packages not marked for install */ -bool pkgAllUpgrade(pkgDepCache &Cache) -{ - return pkgAllUpgradeNoNewPackages(Cache); -} - /*}}}*/ -// MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/ -// --------------------------------------------------------------------- -/* This simply goes over the entire set of packages and tries to keep - each package marked for upgrade. If a conflict is generated then - the package is restored. */ -bool pkgMinimizeUpgrade(pkgDepCache &Cache) -{ - pkgDepCache::ActionGroup group(Cache); - - if (Cache.BrokenCount() != 0) - return false; - - // We loop for 10 tries to get the minimal set size. - bool Change = false; - unsigned int Count = 0; - do - { - Change = false; - for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) - { - // Not interesting - if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true) - continue; - - // Keep it and see if that is OK - Cache.MarkKeep(I, false, false); - if (Cache.BrokenCount() != 0) - Cache.MarkInstall(I, false, 0, false); - else - { - // If keep didnt actually do anything then there was no change.. - if (Cache[I].Upgrade() == false) - Change = true; - } - } - ++Count; - } - while (Change == true && Count < 10); - - if (Cache.BrokenCount() != 0) - return _error->Error("Internal Error in pkgMinimizeUpgrade"); - - return true; -} - /*}}}*/ -// APT::Upgrade::Upgrade - Upgrade using a specific strategy /*{{{*/ -bool APT::Upgrade::Upgrade(pkgDepCache &Cache, int mode) -{ - if (mode == 0) - { - return pkgDistUpgrade(Cache); - } - else if ((mode & ~FORBID_REMOVE_PACKAGES) == 0) - { - return pkgAllUpgradeWithNewPackages(Cache); - } - else if ((mode & ~(FORBID_REMOVE_PACKAGES|FORBID_NEW_INSTALL_PACKAGES)) == 0) - { - return pkgAllUpgradeNoNewPackages(Cache); - } - else - _error->Error("pkgAllUpgrade called with unsupported mode %i", mode); - - return false; -} - /*}}}*/ // ProblemResolver::pkgProblemResolver - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h index d0de72462..9dfa1538a 100644 --- a/apt-pkg/algorithms.h +++ b/apt-pkg/algorithms.h @@ -40,21 +40,16 @@ #ifndef APT_8_CLEANER_HEADERS #include +// include pkg{DistUpgrade,AllUpgrade,MiniizeUpgrade} here for compatiblity using std::ostream; #endif +#ifndef APT_9_CLEANER_HEADERS +#include +#endif + class pkgAcquireStatus; -namespace APT { - namespace Upgrade { - // FIXME: make this "enum class UpgradeMode {" once we enable c++11 - enum UpgradeMode { - FORBID_REMOVE_PACKAGES = 1, - FORBID_NEW_INSTALL_PACKAGES = 2, - }; - bool Upgrade(pkgDepCache &Cache, int UpgradeMode); - } -} class pkgSimulate : public pkgPackageManager /*{{{*/ { @@ -152,14 +147,9 @@ class pkgProblemResolver /*{{{*/ ~pkgProblemResolver(); }; /*}}}*/ -bool pkgDistUpgrade(pkgDepCache &Cache); bool pkgApplyStatus(pkgDepCache &Cache); bool pkgFixBroken(pkgDepCache &Cache); -bool pkgAllUpgrade(pkgDepCache &Cache); - -bool pkgMinimizeUpgrade(pkgDepCache &Cache); - void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List); bool ListUpdate(pkgAcquireStatus &progress, pkgSourceList &List, int PulseInterval=0); diff --git a/apt-pkg/makefile b/apt-pkg/makefile index 59729faf5..262f8fd41 100644 --- a/apt-pkg/makefile +++ b/apt-pkg/makefile @@ -43,7 +43,8 @@ SOURCE+= pkgcache.cc version.cc depcache.cc \ srcrecords.cc cachefile.cc versionmatch.cc policy.cc \ pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc \ indexrecords.cc vendor.cc vendorlist.cc cdrom.cc indexcopy.cc \ - aptconfiguration.cc cachefilter.cc cacheset.cc edsp.cc + aptconfiguration.cc cachefilter.cc cacheset.cc edsp.cc \ + upgrade.cc HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \ orderlist.h sourcelist.h packagemanager.h tagfile.h \ init.h pkgcache.h version.h progress.h pkgrecords.h \ @@ -51,7 +52,7 @@ HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \ clean.h srcrecords.h cachefile.h versionmatch.h policy.h \ pkgsystem.h indexfile.h metaindex.h indexrecords.h vendor.h \ vendorlist.h cdrom.h indexcopy.h aptconfiguration.h \ - cachefilter.h cacheset.h edsp.h + cachefilter.h cacheset.h edsp.h upgrade.h # Source code for the debian specific components # In theory the deb headers do not need to be exported.. diff --git a/apt-pkg/upgrade.cc b/apt-pkg/upgrade.cc new file mode 100644 index 000000000..84c781c61 --- /dev/null +++ b/apt-pkg/upgrade.cc @@ -0,0 +1,263 @@ + +// Include Files /*{{{*/ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + /*}}}*/ + +// DistUpgrade - Distribution upgrade /*{{{*/ +// --------------------------------------------------------------------- +/* This autoinstalls every package and then force installs every + pre-existing package. This creates the initial set of conditions which + most likely contain problems because too many things were installed. + + The problem resolver is used to resolve the problems. + */ +bool pkgDistUpgrade(pkgDepCache &Cache) +{ + std::string const solver = _config->Find("APT::Solver", "internal"); + if (solver != "internal") { + OpTextProgress Prog(*_config); + return EDSP::ResolveExternal(solver.c_str(), Cache, false, true, false, &Prog); + } + + pkgDepCache::ActionGroup group(Cache); + + /* Upgrade all installed packages first without autoinst to help the resolver + in versioned or-groups to upgrade the old solver instead of installing + a new one (if the old solver is not the first one [anymore]) */ + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) + if (I->CurrentVer != 0) + Cache.MarkInstall(I, false, 0, false); + + /* Auto upgrade all installed packages, this provides the basis + for the installation */ + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) + if (I->CurrentVer != 0) + Cache.MarkInstall(I, true, 0, false); + + /* Now, install each essential package which is not installed + (and not provided by another package in the same name group) */ + std::string essential = _config->Find("pkgCacheGen::Essential", "all"); + if (essential == "all") + { + for (pkgCache::GrpIterator G = Cache.GrpBegin(); G.end() == false; ++G) + { + bool isEssential = false; + bool instEssential = false; + for (pkgCache::PkgIterator P = G.PackageList(); P.end() == false; P = G.NextPkg(P)) + { + if ((P->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential) + continue; + isEssential = true; + if (Cache[P].Install() == true) + { + instEssential = true; + break; + } + } + if (isEssential == false || instEssential == true) + continue; + pkgCache::PkgIterator P = G.FindPreferredPkg(); + Cache.MarkInstall(P, true, 0, false); + } + } + else if (essential != "none") + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) + if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) + Cache.MarkInstall(I, true, 0, false); + + /* We do it again over all previously installed packages to force + conflict resolution on them all. */ + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) + if (I->CurrentVer != 0) + Cache.MarkInstall(I, false, 0, false); + + pkgProblemResolver Fix(&Cache); + + // Hold back held packages. + if (_config->FindB("APT::Ignore-Hold",false) == false) + { + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) + { + if (I->SelectedState == pkgCache::State::Hold) + { + Fix.Protect(I); + Cache.MarkKeep(I, false, false); + } + } + } + + return Fix.Resolve(); +} + /*}}}*/ +// AllUpgradeNoNewPackages - Upgrade but no removals or new pkgs /*{{{*/ +static bool pkgAllUpgradeNoNewPackages(pkgDepCache &Cache) +{ + std::string const solver = _config->Find("APT::Solver", "internal"); + if (solver != "internal") { + OpTextProgress Prog(*_config); + return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, &Prog); + } + + pkgDepCache::ActionGroup group(Cache); + + pkgProblemResolver Fix(&Cache); + + if (Cache.BrokenCount() != 0) + return false; + + // Upgrade all installed packages + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) + { + if (Cache[I].Install() == true) + Fix.Protect(I); + + if (_config->FindB("APT::Ignore-Hold",false) == false) + if (I->SelectedState == pkgCache::State::Hold) + continue; + + if (I->CurrentVer != 0 && Cache[I].InstallVer != 0) + Cache.MarkInstall(I, false, 0, false); + } + + return Fix.ResolveByKeep(); +} + /*}}}*/ +// AllUpgradeWithNewInstalls - Upgrade + install new packages as needed /*{{{*/ +// --------------------------------------------------------------------- +/* Right now the system must be consistent before this can be called. + * Upgrade as much as possible without deleting anything (useful for + * stable systems) + */ +static bool pkgAllUpgradeWithNewPackages(pkgDepCache &Cache) +{ + pkgDepCache::ActionGroup group(Cache); + + pkgProblemResolver Fix(&Cache); + + if (Cache.BrokenCount() != 0) + return false; + + // provide the initial set of stuff we want to upgrade by marking + // all upgradable packages for upgrade + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) + { + if (I->CurrentVer != 0 && Cache[I].InstallVer != 0) + { + if (_config->FindB("APT::Ignore-Hold",false) == false) + if (I->SelectedState == pkgCache::State::Hold) + continue; + + Cache.MarkInstall(I, false, 0, false); + } + } + + // then let auto-install loose + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) + if (Cache[I].Install()) + Cache.MarkInstall(I, true, 0, false); + + // ... but it may remove stuff, we we need to clean up afterwards again + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) + if (Cache[I].Delete() == true) + Cache.MarkKeep(I, false, false); + + // resolve remaining issues via keep + return Fix.ResolveByKeep(); +} + /*}}}*/ +// AllUpgrade - Upgrade as many packages as possible /*{{{*/ +// --------------------------------------------------------------------- +/* Right now the system must be consistent before this can be called. + It also will not change packages marked for install, it only tries + to install packages not marked for install */ +bool pkgAllUpgrade(pkgDepCache &Cache) +{ + return pkgAllUpgradeNoNewPackages(Cache); +} + /*}}}*/ +// MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/ +// --------------------------------------------------------------------- +/* This simply goes over the entire set of packages and tries to keep + each package marked for upgrade. If a conflict is generated then + the package is restored. */ +bool pkgMinimizeUpgrade(pkgDepCache &Cache) +{ + pkgDepCache::ActionGroup group(Cache); + + if (Cache.BrokenCount() != 0) + return false; + + // We loop for 10 tries to get the minimal set size. + bool Change = false; + unsigned int Count = 0; + do + { + Change = false; + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) + { + // Not interesting + if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true) + continue; + + // Keep it and see if that is OK + Cache.MarkKeep(I, false, false); + if (Cache.BrokenCount() != 0) + Cache.MarkInstall(I, false, 0, false); + else + { + // If keep didnt actually do anything then there was no change.. + if (Cache[I].Upgrade() == false) + Change = true; + } + } + ++Count; + } + while (Change == true && Count < 10); + + if (Cache.BrokenCount() != 0) + return _error->Error("Internal Error in pkgMinimizeUpgrade"); + + return true; +} + /*}}}*/ +// APT::Upgrade::Upgrade - Upgrade using a specific strategy /*{{{*/ +bool APT::Upgrade::Upgrade(pkgDepCache &Cache, int mode) +{ + if (mode == 0) + { + return pkgDistUpgrade(Cache); + } + else if ((mode & ~FORBID_REMOVE_PACKAGES) == 0) + { + return pkgAllUpgradeWithNewPackages(Cache); + } + else if ((mode & ~(FORBID_REMOVE_PACKAGES|FORBID_NEW_INSTALL_PACKAGES)) == 0) + { + return pkgAllUpgradeNoNewPackages(Cache); + } + else + _error->Error("pkgAllUpgrade called with unsupported mode %i", mode); + + return false; +} + /*}}}*/ diff --git a/apt-pkg/upgrade.h b/apt-pkg/upgrade.h new file mode 100644 index 000000000..9fdfac2fd --- /dev/null +++ b/apt-pkg/upgrade.h @@ -0,0 +1,29 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/* ###################################################################### + + Upgrade - Upgrade/DistUpgrade releated code + + ##################################################################### */ + /*}}}*/ + +#ifndef PKGLIB_UPGRADE_H +#define PKGLIB_UPGRADE_H + +namespace APT { + namespace Upgrade { + // FIXME: make this "enum class UpgradeMode {" once we enable c++11 + enum UpgradeMode { + FORBID_REMOVE_PACKAGES = 1, + FORBID_NEW_INSTALL_PACKAGES = 2, + }; + bool Upgrade(pkgDepCache &Cache, int UpgradeMode); + } +} + +bool pkgDistUpgrade(pkgDepCache &Cache); +bool pkgAllUpgrade(pkgDepCache &Cache); +bool pkgMinimizeUpgrade(pkgDepCache &Cache); + + +#endif -- cgit v1.2.3 From d428d131a29a08fa7c1d95b98b684fb2ebb554c0 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 5 Oct 2013 12:22:55 +0200 Subject: Move ListUpdate/AquireUpdate into update.{cc,h} This moves the ListUpdate/AquireUpdate out of the "catch-all" algorithm.{cc,h} file into its own update.{cc,h} --- apt-pkg/algorithms.cc | 99 --------------------------------------- apt-pkg/algorithms.h | 6 +-- apt-pkg/makefile | 4 +- apt-pkg/update.cc | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++ apt-pkg/update.h | 21 +++++++++ 5 files changed, 150 insertions(+), 106 deletions(-) create mode 100644 apt-pkg/update.cc create mode 100644 apt-pkg/update.h (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 22701f8a6..8644a8138 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -1337,102 +1337,3 @@ void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List) qsort(List,Count,sizeof(*List),PrioComp); } /*}}}*/ -// ListUpdate - construct Fetcher and update the cache files /*{{{*/ -// --------------------------------------------------------------------- -/* This is a simple wrapper to update the cache. it will fetch stuff - * from the network (or any other sources defined in sources.list) - */ -bool ListUpdate(pkgAcquireStatus &Stat, - pkgSourceList &List, - int PulseInterval) -{ - pkgAcquire Fetcher; - if (Fetcher.Setup(&Stat, _config->FindDir("Dir::State::Lists")) == false) - return false; - - // Populate it with the source selection - if (List.GetIndexes(&Fetcher) == false) - return false; - - return AcquireUpdate(Fetcher, PulseInterval, true); -} - /*}}}*/ -// AcquireUpdate - take Fetcher and update the cache files /*{{{*/ -// --------------------------------------------------------------------- -/* This is a simple wrapper to update the cache with a provided acquire - * If you only need control over Status and the used SourcesList use - * ListUpdate method instead. - */ -bool AcquireUpdate(pkgAcquire &Fetcher, int const PulseInterval, - bool const RunUpdateScripts, bool const ListCleanup) -{ - // Run scripts - if (RunUpdateScripts == true) - RunScripts("APT::Update::Pre-Invoke"); - - pkgAcquire::RunResult res; - if(PulseInterval > 0) - res = Fetcher.Run(PulseInterval); - else - res = Fetcher.Run(); - - if (res == pkgAcquire::Failed) - return false; - - bool Failed = false; - bool TransientNetworkFailure = false; - for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); - I != Fetcher.ItemsEnd(); ++I) - { - if ((*I)->Status == pkgAcquire::Item::StatDone) - continue; - - (*I)->Finished(); - - ::URI uri((*I)->DescURI()); - uri.User.clear(); - uri.Password.clear(); - string descUri = string(uri); - _error->Warning(_("Failed to fetch %s %s\n"), descUri.c_str(), - (*I)->ErrorText.c_str()); - - if ((*I)->Status == pkgAcquire::Item::StatTransientNetworkError) - { - TransientNetworkFailure = true; - continue; - } - - Failed = true; - } - - // Clean out any old list files - // Keep "APT::Get::List-Cleanup" name for compatibility, but - // this is really a global option for the APT library now - if (!TransientNetworkFailure && !Failed && ListCleanup == true && - (_config->FindB("APT::Get::List-Cleanup",true) == true && - _config->FindB("APT::List-Cleanup",true) == true)) - { - if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false || - Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false) - // something went wrong with the clean - return false; - } - - if (TransientNetworkFailure == true) - _error->Warning(_("Some index files failed to download. They have been ignored, or old ones used instead.")); - else if (Failed == true) - return _error->Error(_("Some index files failed to download. They have been ignored, or old ones used instead.")); - - - // Run the success scripts if all was fine - if (RunUpdateScripts == true) - { - if(!TransientNetworkFailure && !Failed) - RunScripts("APT::Update::Post-Invoke-Success"); - - // Run the other scripts - RunScripts("APT::Update::Post-Invoke"); - } - return true; -} - /*}}}*/ diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h index 9dfa1538a..80f6578eb 100644 --- a/apt-pkg/algorithms.h +++ b/apt-pkg/algorithms.h @@ -46,10 +46,9 @@ using std::ostream; #ifndef APT_9_CLEANER_HEADERS #include +#include #endif -class pkgAcquireStatus; - class pkgSimulate : public pkgPackageManager /*{{{*/ { @@ -152,8 +151,5 @@ bool pkgFixBroken(pkgDepCache &Cache); void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List); -bool ListUpdate(pkgAcquireStatus &progress, pkgSourceList &List, int PulseInterval=0); -bool AcquireUpdate(pkgAcquire &Fetcher, int const PulseInterval = 0, - bool const RunUpdateScripts = true, bool const ListCleanup = true); #endif diff --git a/apt-pkg/makefile b/apt-pkg/makefile index 262f8fd41..dc943aad4 100644 --- a/apt-pkg/makefile +++ b/apt-pkg/makefile @@ -44,7 +44,7 @@ SOURCE+= pkgcache.cc version.cc depcache.cc \ pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc \ indexrecords.cc vendor.cc vendorlist.cc cdrom.cc indexcopy.cc \ aptconfiguration.cc cachefilter.cc cacheset.cc edsp.cc \ - upgrade.cc + upgrade.cc update.cc HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \ orderlist.h sourcelist.h packagemanager.h tagfile.h \ init.h pkgcache.h version.h progress.h pkgrecords.h \ @@ -52,7 +52,7 @@ HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \ clean.h srcrecords.h cachefile.h versionmatch.h policy.h \ pkgsystem.h indexfile.h metaindex.h indexrecords.h vendor.h \ vendorlist.h cdrom.h indexcopy.h aptconfiguration.h \ - cachefilter.h cacheset.h edsp.h upgrade.h + cachefilter.h cacheset.h edsp.h upgrade.h update.h # Source code for the debian specific components # In theory the deb headers do not need to be exported.. diff --git a/apt-pkg/update.cc b/apt-pkg/update.cc new file mode 100644 index 000000000..97be5490b --- /dev/null +++ b/apt-pkg/update.cc @@ -0,0 +1,126 @@ + +// Include Files /*{{{*/ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + /*}}}*/ + +using namespace std; + +// ListUpdate - construct Fetcher and update the cache files /*{{{*/ +// --------------------------------------------------------------------- +/* This is a simple wrapper to update the cache. it will fetch stuff + * from the network (or any other sources defined in sources.list) + */ +bool ListUpdate(pkgAcquireStatus &Stat, + pkgSourceList &List, + int PulseInterval) +{ + pkgAcquire Fetcher; + if (Fetcher.Setup(&Stat, _config->FindDir("Dir::State::Lists")) == false) + return false; + + // Populate it with the source selection + if (List.GetIndexes(&Fetcher) == false) + return false; + + return AcquireUpdate(Fetcher, PulseInterval, true); +} + /*}}}*/ +// AcquireUpdate - take Fetcher and update the cache files /*{{{*/ +// --------------------------------------------------------------------- +/* This is a simple wrapper to update the cache with a provided acquire + * If you only need control over Status and the used SourcesList use + * ListUpdate method instead. + */ +bool AcquireUpdate(pkgAcquire &Fetcher, int const PulseInterval, + bool const RunUpdateScripts, bool const ListCleanup) +{ + // Run scripts + if (RunUpdateScripts == true) + RunScripts("APT::Update::Pre-Invoke"); + + pkgAcquire::RunResult res; + if(PulseInterval > 0) + res = Fetcher.Run(PulseInterval); + else + res = Fetcher.Run(); + + if (res == pkgAcquire::Failed) + return false; + + bool Failed = false; + bool TransientNetworkFailure = false; + for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); + I != Fetcher.ItemsEnd(); ++I) + { + if ((*I)->Status == pkgAcquire::Item::StatDone) + continue; + + (*I)->Finished(); + + ::URI uri((*I)->DescURI()); + uri.User.clear(); + uri.Password.clear(); + string descUri = string(uri); + _error->Warning(_("Failed to fetch %s %s\n"), descUri.c_str(), + (*I)->ErrorText.c_str()); + + if ((*I)->Status == pkgAcquire::Item::StatTransientNetworkError) + { + TransientNetworkFailure = true; + continue; + } + + Failed = true; + } + + // Clean out any old list files + // Keep "APT::Get::List-Cleanup" name for compatibility, but + // this is really a global option for the APT library now + if (!TransientNetworkFailure && !Failed && ListCleanup == true && + (_config->FindB("APT::Get::List-Cleanup",true) == true && + _config->FindB("APT::List-Cleanup",true) == true)) + { + if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false || + Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false) + // something went wrong with the clean + return false; + } + + if (TransientNetworkFailure == true) + _error->Warning(_("Some index files failed to download. They have been ignored, or old ones used instead.")); + else if (Failed == true) + return _error->Error(_("Some index files failed to download. They have been ignored, or old ones used instead.")); + + + // Run the success scripts if all was fine + if (RunUpdateScripts == true) + { + if(!TransientNetworkFailure && !Failed) + RunScripts("APT::Update::Post-Invoke-Success"); + + // Run the other scripts + RunScripts("APT::Update::Post-Invoke"); + } + return true; +} + /*}}}*/ diff --git a/apt-pkg/update.h b/apt-pkg/update.h new file mode 100644 index 000000000..3835644de --- /dev/null +++ b/apt-pkg/update.h @@ -0,0 +1,21 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/* ###################################################################### + + Update - ListUpdate releated code + + ##################################################################### */ + /*}}}*/ + +#ifndef PKGLIB_UPDATE_H +#define PKGLIB_UPDATE_H + +class pkgAcquireStatus; + + +bool ListUpdate(pkgAcquireStatus &progress, pkgSourceList &List, int PulseInterval=0); +bool AcquireUpdate(pkgAcquire &Fetcher, int const PulseInterval = 0, + bool const RunUpdateScripts = true, bool const ListCleanup = true); + + +#endif -- cgit v1.2.3 From af6b41692b21a7fd1561d9ad4b3e4407ab93246f Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 7 Oct 2013 10:26:50 +0200 Subject: add -o DpkgPM::Progress-Fancy for better dpkg progress output on vt100+ terminals --- apt-pkg/deb/dpkgpm.cc | 88 +++++++++++++++++++++++++++++++++++++++++++++------ apt-pkg/deb/dpkgpm.h | 2 ++ 2 files changed, 81 insertions(+), 9 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index a5097a04f..4eb373fb7 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -54,9 +54,15 @@ class pkgDPkgPMPrivate public: pkgDPkgPMPrivate() : stdin_is_dev_null(false), dpkgbuf_pos(0), term_out(NULL), history_out(NULL), - last_reported_progress(0.0) + last_reported_progress(0.0), nr_terminal_rows(0), + fancy_progress_output(false) { dpkgbuf[0] = '\0'; + if(_config->FindB("DpkgPM::Progress-Fancy", false)) + { + fancy_progress_output = true; + _config->Set("DpkgPM::Progress", true); + } } bool stdin_is_dev_null; // the buffer we use for the dpkg status-fd reading @@ -67,6 +73,8 @@ public: string dpkg_error; float last_reported_progress; + int nr_terminal_rows; + bool fancy_progress_output; }; namespace @@ -892,10 +900,37 @@ void pkgDPkgPM::SendTerminalProgress(float percentage) if(percentage < (d->last_reported_progress + reporting_steps)) return; - // FIXME: use colors too - std::cout << "\r\n" - << "Progress: [" << std::setw(3) << int(percentage) << "%]" - << "\r\n"; + std::string progress_str; + strprintf(progress_str, "Progress: [%3i%%]", (int)percentage); + if (d->fancy_progress_output) + { + int row = d->nr_terminal_rows; + + static string save_cursor = "\033[s"; + static string restore_cursor = "\033[u"; + + static string set_bg_color = "\033[42m"; // green + static string set_fg_color = "\033[30m"; // black + + static string restore_bg = "\033[49m"; + static string restore_fg = "\033[39m"; + + std::cout << save_cursor + // move cursor position to last row + << "\033[" << row << ";0f" + << set_bg_color + << set_fg_color + << progress_str + << restore_cursor + << restore_bg + << restore_fg; + } + else + { + std::cout << progress_str << "\r\n"; + } + std::flush(std::cout); + d->last_reported_progress = percentage; } /*}}}*/ @@ -920,6 +955,29 @@ static int racy_pselect(int nfds, fd_set *readfds, fd_set *writefds, return retval; } /*}}}*/ + +void pkgDPkgPM::SetupTerminalScrollArea(int nr_rows) +{ + if(!d->fancy_progress_output) + return; + + // scroll down a bit to avoid visual glitch when the screen + // area shrinks by one row + std::cout << "\n\n"; + + // save cursor + std::cout << "\033[s"; + + // set scroll region (this will place the cursor in the top left) + std::cout << "\033[1;" << nr_rows - 1 << "r"; + + // restore cursor but ensure its inside the scrolling area + std::cout << "\033[u"; + static const char *move_cursor_up = "\033[1A"; + std::cout << move_cursor_up; + std::flush(std::cout); +} + // DPkgPM::Go - Run the sequence /*{{{*/ // --------------------------------------------------------------------- /* This globs the operations and calls dpkg @@ -1276,7 +1334,8 @@ bool pkgDPkgPM::Go(int OutStatusFd) _error->PushToStack(); if (tcgetattr(STDOUT_FILENO, &tt) == 0) { - ioctl(0, TIOCGWINSZ, (char *)&win); + ioctl(1, TIOCGWINSZ, (char *)&win); + d->nr_terminal_rows = win.ws_row; if (openpty(&master, &slave, NULL, &tt, &win) < 0) { _error->Errno("openpty", _("Can not write log (%s)"), _("Is /dev/pts mounted?")); @@ -1318,11 +1377,12 @@ bool pkgDPkgPM::Go(int OutStatusFd) << endl; FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); } + Child = ExecFork(); - // This is the child if (Child == 0) { + if(slave >= 0 && master >= 0) { setsid(); @@ -1339,7 +1399,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) if (chdir(_config->FindDir("DPkg::Run-Directory","/").c_str()) != 0) _exit(100); - + if (_config->FindB("DPkg::FlushSTDIN",true) == true && isatty(STDIN_FILENO)) { int Flags,dummy; @@ -1355,6 +1415,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) if (fcntl(STDIN_FILENO,F_SETFL,Flags & (~(long)O_NONBLOCK)) < 0) _exit(100); } + SetupTerminalScrollArea(d->nr_terminal_rows); /* No Job Control Stop Env is a magic dpkg var that prevents it from using sigstop */ @@ -1449,6 +1510,15 @@ bool pkgDPkgPM::Go(int OutStatusFd) signal(SIGHUP,old_SIGHUP); + // reset scroll area + SetupTerminalScrollArea(d->nr_terminal_rows); + if(d->fancy_progress_output) + { + // override the progress line (sledgehammer) + static const char* clear_screen_below_cursor = "\033[J"; + std::cout << clear_screen_below_cursor; + } + if(master >= 0) { tcsetattr(0, TCSAFLUSH, &tt); @@ -1488,7 +1558,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) // dpkg is done at this point if(_config->FindB("DPkgPM::Progress", false) == true) SendTerminalProgress(100); - + if (pkgPackageManager::SigINTStop) _error->Warning(_("Operation was interrupted before it could finish")); diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index 29901a204..3b8d36623 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -84,6 +84,8 @@ class pkgDPkgPM : public pkgPackageManager bool SendPkgsInfo(FILE * const F, unsigned int const &Version); void WriteHistoryTag(std::string const &tag, std::string value); + // Terminal progress + void SetupTerminalScrollArea(int nr_scrolled_rows); void SendTerminalProgress(float percentage); // apport integration -- cgit v1.2.3 From 1c6089d72ddf59875fae4f281f023abba0d4fda0 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 7 Oct 2013 13:37:28 +0200 Subject: use Dpkg::Progress-Fancy to be consitent with Dpkg::Progress --- apt-pkg/deb/dpkgpm.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 4eb373fb7..a116db9cf 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -58,7 +58,7 @@ public: fancy_progress_output(false) { dpkgbuf[0] = '\0'; - if(_config->FindB("DpkgPM::Progress-Fancy", false)) + if(_config->FindB("Dpkg::Progress-Fancy", false) == true) { fancy_progress_output = true; _config->Set("DpkgPM::Progress", true); -- cgit v1.2.3 From 3286ad136cbfdb73b97f880ba1ad19a2000781c5 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 7 Oct 2013 13:42:50 +0200 Subject: fix libapt-inst for >2G debs (closes: #725483) --- apt-pkg/contrib/fileutl.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 3966eb0ed..0261119ba 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -656,9 +656,9 @@ string flNoLink(string File) while (1) { // Read the link - int Res; + ssize_t Res; if ((Res = readlink(NFile.c_str(),Buffer,sizeof(Buffer))) <= 0 || - (unsigned)Res >= sizeof(Buffer)) + (size_t)Res >= sizeof(Buffer)) return File; // Append or replace the previous path @@ -1244,7 +1244,7 @@ FileFd::~FileFd() gracefully. */ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual) { - int Res; + ssize_t Res; errno = 0; if (Actual != 0) *Actual = 0; @@ -1344,7 +1344,7 @@ char* FileFd::ReadLine(char *To, unsigned long long const Size) /* */ bool FileFd::Write(const void *From,unsigned long long Size) { - int Res; + ssize_t Res; errno = 0; do { @@ -1398,7 +1398,7 @@ bool FileFd::Write(const void *From,unsigned long long Size) } bool FileFd::Write(int Fd, const void *From, unsigned long long Size) { - int Res; + ssize_t Res; errno = 0; do { @@ -1471,14 +1471,14 @@ bool FileFd::Seek(unsigned long long To) d->seekpos = To; return true; } - int res; + off_t res; #ifdef HAVE_ZLIB if (d != NULL && d->gz) res = gzseek(d->gz,To,SEEK_SET); else #endif res = lseek(iFd,To,SEEK_SET); - if (res != (signed)To) + if (res != (off_t)To) return FileFdError("Unable to seek to %llu", To); if (d != NULL) @@ -1509,7 +1509,7 @@ bool FileFd::Skip(unsigned long long Over) return true; } - int res; + off_t res; #ifdef HAVE_ZLIB if (d != NULL && d->gz != NULL) res = gzseek(d->gz,Over,SEEK_CUR); -- cgit v1.2.3 From 28e3b6f6f822a640aec35a41d5e99a97cfa1e9b1 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 7 Oct 2013 13:46:30 +0200 Subject: fix off-by-one error in pkgDPkgPM::SetupTerminalScrollArea() --- apt-pkg/deb/dpkgpm.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index a116db9cf..7d8c9b4e0 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -963,7 +963,7 @@ void pkgDPkgPM::SetupTerminalScrollArea(int nr_rows) // scroll down a bit to avoid visual glitch when the screen // area shrinks by one row - std::cout << "\n\n"; + std::cout << "\n"; // save cursor std::cout << "\033[s"; -- cgit v1.2.3 From 77fdc2a4de43144432ef9e74058634e94e45ef65 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 8 Oct 2013 21:48:14 +0200 Subject: apt-pkg/deb/dpkgpm.cc: fix off-by-one in SetupTerminalScrollArea reset --- apt-pkg/deb/dpkgpm.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 7d8c9b4e0..b4d812d26 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1511,7 +1511,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) signal(SIGHUP,old_SIGHUP); // reset scroll area - SetupTerminalScrollArea(d->nr_terminal_rows); + SetupTerminalScrollArea(d->nr_terminal_rows + 1); if(d->fancy_progress_output) { // override the progress line (sledgehammer) -- cgit v1.2.3 From 31f97d7b862ccf3de93b30a15f24d76e806031a3 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 11 Oct 2013 19:27:23 +0200 Subject: first iteration of install progress refactor --- apt-pkg/deb/dpkgpm.cc | 111 +++++++++-------------------------------------- apt-pkg/deb/dpkgpm.h | 1 + apt-pkg/iprogress.cc | 111 +++++++++++++++++++++++++++++++++++++++++++++++ apt-pkg/iprogress.h | 59 +++++++++++++++++++++++++ apt-pkg/makefile | 4 +- apt-pkg/packagemanager.h | 1 + 6 files changed, 194 insertions(+), 93 deletions(-) create mode 100644 apt-pkg/iprogress.cc create mode 100644 apt-pkg/iprogress.h (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index b4d812d26..cd4f5c31e 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -54,16 +55,21 @@ class pkgDPkgPMPrivate public: pkgDPkgPMPrivate() : stdin_is_dev_null(false), dpkgbuf_pos(0), term_out(NULL), history_out(NULL), - last_reported_progress(0.0), nr_terminal_rows(0), - fancy_progress_output(false) + last_reported_progress(0.0) { dpkgbuf[0] = '\0'; - if(_config->FindB("Dpkg::Progress-Fancy", false) == true) - { - fancy_progress_output = true; - _config->Set("DpkgPM::Progress", true); - } + if(_config->FindB("DpkgPM::Progress-Fancy", false) == true) + progress = new APT::Progress::PackageManagerFancy(); + else if (_config->FindB("DpkgPM::Progress", false) == true) + progress = new APT::Progress::PackageManagerText(); + else + progress = new APT::Progress::PackageManager(); } + ~pkgDPkgPMPrivate() + { + delete progress; + } + bool stdin_is_dev_null; // the buffer we use for the dpkg status-fd reading char dpkgbuf[1024]; @@ -73,8 +79,7 @@ public: string dpkg_error; float last_reported_progress; - int nr_terminal_rows; - bool fancy_progress_output; + APT::Progress::PackageManager *progress; }; namespace @@ -644,8 +649,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) << ":" << (PackagesDone/float(PackagesTotal)*100.0) << ":" << s << endl; - if(_config->FindB("DPkgPM::Progress", false) == true) - SendTerminalProgress(PackagesDone/float(PackagesTotal)*100.0); + d->progress->StatusChanged(pkg, PackagesDone, PackagesTotal); if(OutStatusFd > 0) FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); @@ -889,52 +893,6 @@ bool pkgDPkgPM::CloseLog() return true; } /*}}}*/ -// DPkgPM::SendTerminalProgress /*{{{*/ -// --------------------------------------------------------------------- -/* Send progress info to the terminal - */ -void pkgDPkgPM::SendTerminalProgress(float percentage) -{ - int reporting_steps = _config->FindI("DpkgPM::Reporting-Steps", 1); - - if(percentage < (d->last_reported_progress + reporting_steps)) - return; - - std::string progress_str; - strprintf(progress_str, "Progress: [%3i%%]", (int)percentage); - if (d->fancy_progress_output) - { - int row = d->nr_terminal_rows; - - static string save_cursor = "\033[s"; - static string restore_cursor = "\033[u"; - - static string set_bg_color = "\033[42m"; // green - static string set_fg_color = "\033[30m"; // black - - static string restore_bg = "\033[49m"; - static string restore_fg = "\033[39m"; - - std::cout << save_cursor - // move cursor position to last row - << "\033[" << row << ";0f" - << set_bg_color - << set_fg_color - << progress_str - << restore_cursor - << restore_bg - << restore_fg; - } - else - { - std::cout << progress_str << "\r\n"; - } - std::flush(std::cout); - - d->last_reported_progress = percentage; -} - /*}}}*/ -/*{{{*/ // This implements a racy version of pselect for those architectures // that don't have a working implementation. // FIXME: Probably can be removed on Lenny+1 @@ -956,27 +914,6 @@ static int racy_pselect(int nfds, fd_set *readfds, fd_set *writefds, } /*}}}*/ -void pkgDPkgPM::SetupTerminalScrollArea(int nr_rows) -{ - if(!d->fancy_progress_output) - return; - - // scroll down a bit to avoid visual glitch when the screen - // area shrinks by one row - std::cout << "\n"; - - // save cursor - std::cout << "\033[s"; - - // set scroll region (this will place the cursor in the top left) - std::cout << "\033[1;" << nr_rows - 1 << "r"; - - // restore cursor but ensure its inside the scrolling area - std::cout << "\033[u"; - static const char *move_cursor_up = "\033[1A"; - std::cout << move_cursor_up; - std::flush(std::cout); -} // DPkgPM::Go - Run the sequence /*{{{*/ // --------------------------------------------------------------------- @@ -1334,8 +1271,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) _error->PushToStack(); if (tcgetattr(STDOUT_FILENO, &tt) == 0) { - ioctl(1, TIOCGWINSZ, (char *)&win); - d->nr_terminal_rows = win.ws_row; + ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&win); if (openpty(&master, &slave, NULL, &tt, &win) < 0) { _error->Errno("openpty", _("Can not write log (%s)"), _("Is /dev/pts mounted?")); @@ -1415,7 +1351,6 @@ bool pkgDPkgPM::Go(int OutStatusFd) if (fcntl(STDIN_FILENO,F_SETFL,Flags & (~(long)O_NONBLOCK)) < 0) _exit(100); } - SetupTerminalScrollArea(d->nr_terminal_rows); /* No Job Control Stop Env is a magic dpkg var that prevents it from using sigstop */ @@ -1424,6 +1359,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) cerr << "Could not exec dpkg!" << endl; _exit(100); } + d->progress->Started(); // apply ionice if (_config->FindB("DPkg::UseIoNice", false) == true) @@ -1510,14 +1446,8 @@ bool pkgDPkgPM::Go(int OutStatusFd) signal(SIGHUP,old_SIGHUP); - // reset scroll area - SetupTerminalScrollArea(d->nr_terminal_rows + 1); - if(d->fancy_progress_output) - { - // override the progress line (sledgehammer) - static const char* clear_screen_below_cursor = "\033[J"; - std::cout << clear_screen_below_cursor; - } + // tell the progress + d->progress->Finished(); if(master >= 0) { @@ -1556,8 +1486,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) CloseLog(); // dpkg is done at this point - if(_config->FindB("DPkgPM::Progress", false) == true) - SendTerminalProgress(100); + d->progress->StatusChanged("", PackagesDone, PackagesTotal); if (pkgPackageManager::SigINTStop) _error->Warning(_("Operation was interrupted before it could finish")); diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index 3b8d36623..53e352d4e 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -23,6 +23,7 @@ using std::map; class pkgDPkgPMPrivate; + class pkgDPkgPM : public pkgPackageManager { private: diff --git a/apt-pkg/iprogress.cc b/apt-pkg/iprogress.cc new file mode 100644 index 000000000..4de8c0492 --- /dev/null +++ b/apt-pkg/iprogress.cc @@ -0,0 +1,111 @@ +#include +#include + +#include +#include + +namespace APT { +namespace Progress { + +static void SetupTerminalScrollArea(int nr_rows) +{ + // scroll down a bit to avoid visual glitch when the screen + // area shrinks by one row + std::cout << "\n"; + + // save cursor + std::cout << "\033[s"; + + // set scroll region (this will place the cursor in the top left) + std::cout << "\033[1;" << nr_rows - 1 << "r"; + + // restore cursor but ensure its inside the scrolling area + std::cout << "\033[u"; + static const char *move_cursor_up = "\033[1A"; + std::cout << move_cursor_up; + std::flush(std::cout); +} + +PackageManagerFancy::PackageManagerFancy() + : nr_terminal_rows(-1) +{ + struct winsize win; + if(ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&win) == 0) + { + nr_terminal_rows = win.ws_row; + } +} + +void PackageManagerFancy::Started() +{ + SetupTerminalScrollArea(nr_terminal_rows); +} + +void PackageManagerFancy::Finished() +{ + SetupTerminalScrollArea(nr_terminal_rows + 1); + + // override the progress line (sledgehammer) + static const char* clear_screen_below_cursor = "\033[J"; + std::cout << clear_screen_below_cursor; +} + +void PackageManagerFancy::StatusChanged(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps) +{ + int reporting_steps = _config->FindI("DpkgPM::Reporting-Steps", 1); + float percentage = StepsDone/(float)TotalSteps * 100.0; + + if(percentage < (last_reported_progress + reporting_steps)) + return; + + std::string progress_str; + strprintf(progress_str, "Progress: [%3i%%]", (int)percentage); + + int row = nr_terminal_rows; + + static string save_cursor = "\033[s"; + static string restore_cursor = "\033[u"; + + static string set_bg_color = "\033[42m"; // green + static string set_fg_color = "\033[30m"; // black + + static string restore_bg = "\033[49m"; + static string restore_fg = "\033[39m"; + + std::cout << save_cursor + // move cursor position to last row + << "\033[" << row << ";0f" + << set_bg_color + << set_fg_color + << progress_str + << restore_cursor + << restore_bg + << restore_fg; + std::flush(std::cout); + last_reported_progress = percentage; +} + +void PackageManagerText::StatusChanged(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps) +{ + int reporting_steps = _config->FindI("DpkgPM::Reporting-Steps", 1); + float percentage = StepsDone/(float)TotalSteps * 100.0; + + if(percentage < (last_reported_progress + reporting_steps)) + return; + + std::string progress_str; + strprintf(progress_str, "Progress: [%3i%%]", (int)percentage); + + std::cout << progress_str << "\r\n"; + std::flush(std::cout); + + last_reported_progress = percentage; +} + + +}; // namespace progress +}; // namespace apt diff --git a/apt-pkg/iprogress.h b/apt-pkg/iprogress.h new file mode 100644 index 000000000..14fc89bff --- /dev/null +++ b/apt-pkg/iprogress.h @@ -0,0 +1,59 @@ +#ifndef PKGLIB_IPROGRESS_H +#define PKGLIB_IPROGRSS_H + + +#include + +namespace APT { +namespace Progress { + + + class PackageManager + { + private: + /** \brief dpointer placeholder */ + void *d; + + public: + virtual ~PackageManager() {}; + + virtual void Started() {}; + virtual void Finished() {}; + + virtual void StatusChanged(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps) {}; + }; + + class PackageManagerFancy : public PackageManager + { + protected: + int last_reported_progress; + int nr_terminal_rows; + public: + PackageManagerFancy(); + virtual void Started(); + virtual void Finished(); + virtual void StatusChanged(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps); + }; + + class PackageManagerText : public PackageManager + { + protected: + int last_reported_progress; + + public: + PackageManagerText() : last_reported_progress(0) {}; + virtual void StatusChanged(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps); + + }; + + +}; // namespace Progress +}; // namespace APT + +#endif diff --git a/apt-pkg/makefile b/apt-pkg/makefile index 59729faf5..e69b5ce7f 100644 --- a/apt-pkg/makefile +++ b/apt-pkg/makefile @@ -43,7 +43,7 @@ SOURCE+= pkgcache.cc version.cc depcache.cc \ srcrecords.cc cachefile.cc versionmatch.cc policy.cc \ pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc \ indexrecords.cc vendor.cc vendorlist.cc cdrom.cc indexcopy.cc \ - aptconfiguration.cc cachefilter.cc cacheset.cc edsp.cc + aptconfiguration.cc cachefilter.cc cacheset.cc edsp.cc iprogress.cc HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \ orderlist.h sourcelist.h packagemanager.h tagfile.h \ init.h pkgcache.h version.h progress.h pkgrecords.h \ @@ -51,7 +51,7 @@ HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \ clean.h srcrecords.h cachefile.h versionmatch.h policy.h \ pkgsystem.h indexfile.h metaindex.h indexrecords.h vendor.h \ vendorlist.h cdrom.h indexcopy.h aptconfiguration.h \ - cachefilter.h cacheset.h edsp.h + cachefilter.h cacheset.h edsp.h iprogress.h # Source code for the debian specific components # In theory the deb headers do not need to be exported.. diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index 1a6a9f01c..4956e816f 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -39,6 +39,7 @@ class pkgDepCache; class pkgSourceList; class pkgOrderList; class pkgRecords; + class pkgPackageManager : protected pkgCache::Namespace { public: -- cgit v1.2.3 From f28eef6df2a9fd2befedacf8ccd6248e5b3618db Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 11 Oct 2013 22:05:38 +0200 Subject: add missing _() around the new "Progress" string --- apt-pkg/deb/dpkgpm.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index b4d812d26..c29d21574 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -901,7 +901,7 @@ void pkgDPkgPM::SendTerminalProgress(float percentage) return; std::string progress_str; - strprintf(progress_str, "Progress: [%3i%%]", (int)percentage); + strprintf(progress_str, _("Progress: [%3i%%]"), (int)percentage); if (d->fancy_progress_output) { int row = d->nr_terminal_rows; -- cgit v1.2.3 From db78c60c6a726ed70fa8b0984090b80840444016 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 11 Oct 2013 22:16:55 +0200 Subject: deal with nr_terminal_rows unavailable --- apt-pkg/iprogress.cc | 17 +++++++++++------ apt-pkg/iprogress.h | 2 ++ 2 files changed, 13 insertions(+), 6 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/iprogress.cc b/apt-pkg/iprogress.cc index 4de8c0492..68a2c7207 100644 --- a/apt-pkg/iprogress.cc +++ b/apt-pkg/iprogress.cc @@ -7,7 +7,7 @@ namespace APT { namespace Progress { -static void SetupTerminalScrollArea(int nr_rows) +void PackageManagerFancy::SetupTerminalScrollArea(int nr_rows) { // scroll down a bit to avoid visual glitch when the screen // area shrinks by one row @@ -23,6 +23,7 @@ static void SetupTerminalScrollArea(int nr_rows) std::cout << "\033[u"; static const char *move_cursor_up = "\033[1A"; std::cout << move_cursor_up; + std::flush(std::cout); } @@ -38,16 +39,20 @@ PackageManagerFancy::PackageManagerFancy() void PackageManagerFancy::Started() { - SetupTerminalScrollArea(nr_terminal_rows); + if (nr_terminal_rows > 0) + SetupTerminalScrollArea(nr_terminal_rows); } void PackageManagerFancy::Finished() { - SetupTerminalScrollArea(nr_terminal_rows + 1); + if (nr_terminal_rows > 0) + { + SetupTerminalScrollArea(nr_terminal_rows + 1); - // override the progress line (sledgehammer) - static const char* clear_screen_below_cursor = "\033[J"; - std::cout << clear_screen_below_cursor; + // override the progress line (sledgehammer) + static const char* clear_screen_below_cursor = "\033[J"; + std::cout << clear_screen_below_cursor; + } } void PackageManagerFancy::StatusChanged(std::string PackageName, diff --git a/apt-pkg/iprogress.h b/apt-pkg/iprogress.h index 14fc89bff..f097e0943 100644 --- a/apt-pkg/iprogress.h +++ b/apt-pkg/iprogress.h @@ -30,6 +30,8 @@ namespace Progress { protected: int last_reported_progress; int nr_terminal_rows; + void SetupTerminalScrollArea(int nr_rows); + public: PackageManagerFancy(); virtual void Started(); -- cgit v1.2.3 From 6c5ae8ed079e01082f606614641b19b7c08893ad Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 11 Oct 2013 22:48:22 +0200 Subject: move common code into PackageManager::StatusChanged() --- apt-pkg/deb/dpkgpm.cc | 5 +++-- apt-pkg/iprogress.cc | 43 +++++++++++++++++++++++++------------------ apt-pkg/iprogress.h | 19 ++++++++++--------- 3 files changed, 38 insertions(+), 29 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index cd4f5c31e..35adb91f6 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -58,9 +58,10 @@ public: last_reported_progress(0.0) { dpkgbuf[0] = '\0'; - if(_config->FindB("DpkgPM::Progress-Fancy", false) == true) + if(_config->FindB("Dpkg::Progress-Fancy", false) == true) progress = new APT::Progress::PackageManagerFancy(); - else if (_config->FindB("DpkgPM::Progress", false) == true) + else if (_config->FindB("Dpkg::Progress", + _config->FindB("DpkgPM::Progress", false)) == true) progress = new APT::Progress::PackageManagerText(); else progress = new APT::Progress::PackageManager(); diff --git a/apt-pkg/iprogress.cc b/apt-pkg/iprogress.cc index 68a2c7207..398059051 100644 --- a/apt-pkg/iprogress.cc +++ b/apt-pkg/iprogress.cc @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -7,6 +8,20 @@ namespace APT { namespace Progress { +bool PackageManager::StatusChanged(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps) +{ + int reporting_steps = _config->FindI("DpkgPM::Reporting-Steps", 1); + percentage = StepsDone/(float)TotalSteps * 100.0; + strprintf(progress_str, _("Progress: [%3i%%]"), (int)percentage); + + if(percentage < (last_reported_progress + reporting_steps)) + return false; + + return true; +} + void PackageManagerFancy::SetupTerminalScrollArea(int nr_rows) { // scroll down a bit to avoid visual glitch when the screen @@ -55,18 +70,12 @@ void PackageManagerFancy::Finished() } } -void PackageManagerFancy::StatusChanged(std::string PackageName, +bool PackageManagerFancy::StatusChanged(std::string PackageName, unsigned int StepsDone, unsigned int TotalSteps) { - int reporting_steps = _config->FindI("DpkgPM::Reporting-Steps", 1); - float percentage = StepsDone/(float)TotalSteps * 100.0; - - if(percentage < (last_reported_progress + reporting_steps)) - return; - - std::string progress_str; - strprintf(progress_str, "Progress: [%3i%%]", (int)percentage); + if (!PackageManager::StatusChanged(PackageName, StepsDone, TotalSteps)) + return false; int row = nr_terminal_rows; @@ -90,25 +99,23 @@ void PackageManagerFancy::StatusChanged(std::string PackageName, << restore_fg; std::flush(std::cout); last_reported_progress = percentage; + + return true; } -void PackageManagerText::StatusChanged(std::string PackageName, +bool PackageManagerText::StatusChanged(std::string PackageName, unsigned int StepsDone, unsigned int TotalSteps) { - int reporting_steps = _config->FindI("DpkgPM::Reporting-Steps", 1); - float percentage = StepsDone/(float)TotalSteps * 100.0; - - if(percentage < (last_reported_progress + reporting_steps)) - return; - - std::string progress_str; - strprintf(progress_str, "Progress: [%3i%%]", (int)percentage); + if (!PackageManager::StatusChanged(PackageName, StepsDone, TotalSteps)) + return false; std::cout << progress_str << "\r\n"; std::flush(std::cout); last_reported_progress = percentage; + + return true; } diff --git a/apt-pkg/iprogress.h b/apt-pkg/iprogress.h index f097e0943..5f1655ab9 100644 --- a/apt-pkg/iprogress.h +++ b/apt-pkg/iprogress.h @@ -14,21 +14,26 @@ namespace Progress { /** \brief dpointer placeholder */ void *d; + protected: + std::string progress_str; + float percentage; + int last_reported_progress; + public: + PackageManager() : percentage(0.0), last_reported_progress(0) {}; virtual ~PackageManager() {}; virtual void Started() {}; virtual void Finished() {}; - virtual void StatusChanged(std::string PackageName, + virtual bool StatusChanged(std::string PackageName, unsigned int StepsDone, - unsigned int TotalSteps) {}; + unsigned int TotalSteps); }; class PackageManagerFancy : public PackageManager { protected: - int last_reported_progress; int nr_terminal_rows; void SetupTerminalScrollArea(int nr_rows); @@ -36,19 +41,15 @@ namespace Progress { PackageManagerFancy(); virtual void Started(); virtual void Finished(); - virtual void StatusChanged(std::string PackageName, + virtual bool StatusChanged(std::string PackageName, unsigned int StepsDone, unsigned int TotalSteps); }; class PackageManagerText : public PackageManager { - protected: - int last_reported_progress; - public: - PackageManagerText() : last_reported_progress(0) {}; - virtual void StatusChanged(std::string PackageName, + virtual bool StatusChanged(std::string PackageName, unsigned int StepsDone, unsigned int TotalSteps); -- cgit v1.2.3 From e6ad8031b774af9bdd5d460d9983450bb5a03d0d Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sun, 13 Oct 2013 15:05:04 +0200 Subject: move the status-fd progress reporting out of the pkgDPkgPM class, at this point, breaks ABI/API, lets see what we can do about this --- apt-pkg/deb/dpkgpm.cc | 99 ++++++++++++----------------------------------- apt-pkg/deb/dpkgpm.h | 7 ++-- apt-pkg/iprogress.cc | 95 ++++++++++++++++++++++++++++++++++++++++++--- apt-pkg/iprogress.h | 56 +++++++++++++++++++++++---- apt-pkg/packagemanager.cc | 14 ++++--- apt-pkg/packagemanager.h | 18 +++++++-- 6 files changed, 189 insertions(+), 100 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 35adb91f6..0c3be4ce5 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -55,20 +55,12 @@ class pkgDPkgPMPrivate public: pkgDPkgPMPrivate() : stdin_is_dev_null(false), dpkgbuf_pos(0), term_out(NULL), history_out(NULL), - last_reported_progress(0.0) + last_reported_progress(0.0), progress(NULL) { dpkgbuf[0] = '\0'; - if(_config->FindB("Dpkg::Progress-Fancy", false) == true) - progress = new APT::Progress::PackageManagerFancy(); - else if (_config->FindB("Dpkg::Progress", - _config->FindB("DpkgPM::Progress", false)) == true) - progress = new APT::Progress::PackageManagerText(); - else - progress = new APT::Progress::PackageManager(); } ~pkgDPkgPMPrivate() { - delete progress; } bool stdin_is_dev_null; @@ -519,11 +511,9 @@ void pkgDPkgPM::DoTerminalPty(int master) // --------------------------------------------------------------------- /* */ -void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) +void pkgDPkgPM::ProcessDpkgStatusLine(char *line) { bool const Debug = _config->FindB("Debug::pkgDPkgProgressReporting",false); - // the status we output - ostringstream status; if (Debug == true) std::clog << "got from dpkg '" << line << "'" << std::endl; @@ -573,7 +563,6 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) // 'processing: action: pkg' if(strncmp(list[0].c_str(), "processing", strlen("processing")) == 0) { - char s[200]; const char* const pkg_or_trigger = list[2].c_str(); action = list[1].c_str(); const std::pair * const iter = @@ -586,17 +575,11 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) std::clog << "ignoring unknown action: " << action << std::endl; return; } - snprintf(s, sizeof(s), _(iter->second), pkg_or_trigger); - - status << "pmstatus:" << pkg_or_trigger - << ":" << (PackagesDone/float(PackagesTotal)*100.0) - << ":" << s - << endl; - if(OutStatusFd > 0) - FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); - if (Debug == true) - std::clog << "send: '" << status.str() << "'" << endl; + std::string pkg_action; + strprintf(pkg_action, _(iter->second), pkg_or_trigger); + d->progress->StatusChanged(pkg_or_trigger, PackagesDone, PackagesTotal, + pkg_action); if (strncmp(action, "disappear", strlen("disappear")) == 0) handleDisappearAction(pkg_or_trigger); return; @@ -604,28 +587,15 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) if(strncmp(action,"error",strlen("error")) == 0) { - status << "pmerror:" << list[1] - << ":" << (PackagesDone/float(PackagesTotal)*100.0) - << ":" << list[3] - << endl; - if(OutStatusFd > 0) - FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); - if (Debug == true) - std::clog << "send: '" << status.str() << "'" << endl; + d->progress->Error(list[1], PackagesDone, PackagesTotal, list[3]); pkgFailures++; WriteApportReport(list[1].c_str(), list[3].c_str()); return; } else if(strncmp(action,"conffile",strlen("conffile")) == 0) { - status << "pmconffile:" << list[1] - << ":" << (PackagesDone/float(PackagesTotal)*100.0) - << ":" << list[3] - << endl; - if(OutStatusFd > 0) - FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); - if (Debug == true) - std::clog << "send: '" << status.str() << "'" << endl; + d->progress->ConffilePrompt(list[1], PackagesDone, PackagesTotal, + list[3]); return; } @@ -638,24 +608,15 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) { // only read the translation if there is actually a next // action - const char *translation = _(states[PackageOpsDone[pkg]].str); - char s[200]; - snprintf(s, sizeof(s), translation, pkg); + std::string translation; + strprintf(translation, _(states[PackageOpsDone[pkg]].str), pkg); // we moved from one dpkg state to a new one, report that PackageOpsDone[pkg]++; PackagesDone++; - // build the status str - status << "pmstatus:" << pkg - << ":" << (PackagesDone/float(PackagesTotal)*100.0) - << ":" << s - << endl; - d->progress->StatusChanged(pkg, PackagesDone, PackagesTotal); - - if(OutStatusFd > 0) - FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); - if (Debug == true) - std::clog << "send: '" << status.str() << "'" << endl; + // and send to the progress + d->progress->StatusChanged(pkg, PackagesDone, PackagesTotal, + translation); } if (Debug == true) std::clog << "(parsed from dpkg) pkg: " << pkg @@ -713,7 +674,7 @@ void pkgDPkgPM::handleDisappearAction(string const &pkgname) // --------------------------------------------------------------------- /* */ -void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd) +void pkgDPkgPM::DoDpkgStatusFd(int statusfd) { char *p, *q; int len; @@ -728,7 +689,7 @@ void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd) while((q=(char*)memchr(p, '\n', d->dpkgbuf+d->dpkgbuf_pos-p)) != NULL) { *q = 0; - ProcessDpkgStatusLine(OutStatusFd, p); + ProcessDpkgStatusLine(p); p=q+1; // continue with next line } @@ -920,14 +881,15 @@ static int racy_pselect(int nfds, fd_set *readfds, fd_set *writefds, // --------------------------------------------------------------------- /* This globs the operations and calls dpkg * - * If it is called with "OutStatusFd" set to a valid file descriptor - * apt will report the install progress over this fd. It maps the - * dpkg states a package goes through to human readable (and i10n-able) + * If it is called with a progress object apt will report the install + * progress to this object. It maps the dpkg states a package goes + * through to human readable (and i10n-able) * names and calculates a percentage for each step. */ -bool pkgDPkgPM::Go(int OutStatusFd) +bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) { pkgPackageManager::SigINTStop = false; + d->progress = progress; // Generate the base argument list for dpkg std::vector Args; @@ -1304,16 +1266,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) // Fork dpkg pid_t Child; - _config->Set("APT::Keep-Fds::",fd[1]); - // send status information that we are about to fork dpkg - if(OutStatusFd > 0) { - ostringstream status; - status << "pmstatus:dpkg-exec:" - << (PackagesDone/float(PackagesTotal)*100.0) - << ":" << _("Running dpkg") - << endl; - FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); - } + d->progress->Started(); Child = ExecFork(); // This is the child @@ -1360,15 +1313,11 @@ bool pkgDPkgPM::Go(int OutStatusFd) cerr << "Could not exec dpkg!" << endl; _exit(100); } - d->progress->Started(); // apply ionice if (_config->FindB("DPkg::UseIoNice", false) == true) ionice(Child); - // clear the Keep-Fd again - _config->Clear("APT::Keep-Fds",fd[1]); - // Wait for dpkg int Status = 0; @@ -1437,7 +1386,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) if(master >= 0 && FD_ISSET(0, &rfds)) DoStdin(master); if(FD_ISSET(_dpkgin, &rfds)) - DoDpkgStatusFd(_dpkgin, OutStatusFd); + DoDpkgStatusFd(_dpkgin); } close(_dpkgin); @@ -1487,7 +1436,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) CloseLog(); // dpkg is done at this point - d->progress->StatusChanged("", PackagesDone, PackagesTotal); + d->progress->StatusChanged("", PackagesDone, PackagesTotal, ""); if (pkgPackageManager::SigINTStop) _error->Warning(_("Operation was interrupted before it could finish")); diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index 53e352d4e..1f4bbafc7 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -99,14 +99,15 @@ class pkgDPkgPM : public pkgPackageManager // input processing void DoStdin(int master); void DoTerminalPty(int master); - void DoDpkgStatusFd(int statusfd, int OutStatusFd); - void ProcessDpkgStatusLine(int OutStatusFd, char *line); + void DoDpkgStatusFd(int statusfd); + void ProcessDpkgStatusLine(char *line); // The Actuall installation implementation virtual bool Install(PkgIterator Pkg,std::string File); virtual bool Configure(PkgIterator Pkg); virtual bool Remove(PkgIterator Pkg,bool Purge = false); - virtual bool Go(int StatusFd=-1); + + virtual bool Go(APT::Progress::PackageManager *progress); virtual void Reset(); public: diff --git a/apt-pkg/iprogress.cc b/apt-pkg/iprogress.cc index 398059051..6c5d33d4a 100644 --- a/apt-pkg/iprogress.cc +++ b/apt-pkg/iprogress.cc @@ -1,16 +1,22 @@ +#include +#include #include #include + #include #include #include +#include + namespace APT { namespace Progress { bool PackageManager::StatusChanged(std::string PackageName, - unsigned int StepsDone, - unsigned int TotalSteps) + unsigned int StepsDone, + unsigned int TotalSteps, + std::string HumanReadableAction) { int reporting_steps = _config->FindI("DpkgPM::Reporting-Steps", 1); percentage = StepsDone/(float)TotalSteps * 100.0; @@ -22,6 +28,80 @@ bool PackageManager::StatusChanged(std::string PackageName, return true; } +PackageManagerProgressFd::PackageManagerProgressFd(int progress_fd) +{ + OutStatusFd = progress_fd; +} + +void PackageManagerProgressFd::Started() +{ + _config->Set("APT::Keep-Fds::", OutStatusFd); + + // send status information that we are about to fork dpkg + if(OutStatusFd > 0) { + std::ostringstream status; + status << "pmstatus:dpkg-exec:" + << (StepsDone/float(StepsTotal)*100.0) + << ":" << _("Running dpkg") + << std::endl; + FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); + } +} + +void PackageManagerProgressFd::Finished() +{ + // clear the Keep-Fd again + _config->Clear("APT::Keep-Fds", OutStatusFd); +} + +void PackageManagerProgressFd::Error(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ErrorMessage) +{ + std::ostringstream status; + status << "pmerror:" << PackageName + << ":" << (StepsDone/float(TotalSteps)*100.0) + << ":" << ErrorMessage + << std::endl; + if(OutStatusFd > 0) + FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); +} + +void PackageManagerProgressFd::ConffilePrompt(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ConfMessage) +{ + std::ostringstream status; + status << "pmconffile:" << PackageName + << ":" << (StepsDone/float(TotalSteps)*100.0) + << ":" << ConfMessage + << std::endl; + if(OutStatusFd > 0) + FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); +} + + +bool PackageManagerProgressFd::StatusChanged(std::string PackageName, + unsigned int xStepsDone, + unsigned int xTotalSteps, + std::string pkg_action) +{ + StepsDone = xStepsDone; + StepsTotal = xTotalSteps; + + // build the status str + std::ostringstream status; + status << "pmstatus:" << PackageName + << ":" << (StepsDone/float(StepsTotal)*100.0) + << ":" << pkg_action + << std::endl; + if(OutStatusFd > 0) + FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); + return true; +} + void PackageManagerFancy::SetupTerminalScrollArea(int nr_rows) { // scroll down a bit to avoid visual glitch when the screen @@ -72,9 +152,11 @@ void PackageManagerFancy::Finished() bool PackageManagerFancy::StatusChanged(std::string PackageName, unsigned int StepsDone, - unsigned int TotalSteps) + unsigned int TotalSteps, + std::string HumanReadableAction) { - if (!PackageManager::StatusChanged(PackageName, StepsDone, TotalSteps)) + if (!PackageManager::StatusChanged(PackageName, StepsDone, TotalSteps, + HumanReadableAction)) return false; int row = nr_terminal_rows; @@ -105,9 +187,10 @@ bool PackageManagerFancy::StatusChanged(std::string PackageName, bool PackageManagerText::StatusChanged(std::string PackageName, unsigned int StepsDone, - unsigned int TotalSteps) + unsigned int TotalSteps, + std::string HumanReadableAction) { - if (!PackageManager::StatusChanged(PackageName, StepsDone, TotalSteps)) + if (!PackageManager::StatusChanged(PackageName, StepsDone, TotalSteps, HumanReadableAction)) return false; std::cout << progress_str << "\r\n"; diff --git a/apt-pkg/iprogress.h b/apt-pkg/iprogress.h index 5f1655ab9..6519e9445 100644 --- a/apt-pkg/iprogress.h +++ b/apt-pkg/iprogress.h @@ -1,13 +1,13 @@ #ifndef PKGLIB_IPROGRESS_H -#define PKGLIB_IPROGRSS_H +#define PKGLIB_IPROGRESS_H +#include +#include -#include namespace APT { namespace Progress { - class PackageManager { private: @@ -20,15 +20,54 @@ namespace Progress { int last_reported_progress; public: - PackageManager() : percentage(0.0), last_reported_progress(0) {}; + PackageManager() + : percentage(0.0), last_reported_progress(0) {}; virtual ~PackageManager() {}; virtual void Started() {}; virtual void Finished() {}; + + virtual pid_t fork() {return fork(); }; virtual bool StatusChanged(std::string PackageName, unsigned int StepsDone, - unsigned int TotalSteps); + unsigned int TotalSteps, + std::string HumanReadableAction) ; + virtual void Error(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ErrorMessage) {}; + virtual void ConffilePrompt(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ConfMessage) {}; + }; + + class PackageManagerProgressFd : public PackageManager + { + protected: + int OutStatusFd; + int StepsDone; + int StepsTotal; + + public: + PackageManagerProgressFd(int progress_fd); + virtual void Started(); + virtual void Finished(); + + virtual bool StatusChanged(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string HumanReadableAction); + virtual void Error(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ErrorMessage); + virtual void ConffilePrompt(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ConfMessage); + }; class PackageManagerFancy : public PackageManager @@ -43,7 +82,8 @@ namespace Progress { virtual void Finished(); virtual bool StatusChanged(std::string PackageName, unsigned int StepsDone, - unsigned int TotalSteps); + unsigned int TotalSteps, + std::string HumanReadableAction); }; class PackageManagerText : public PackageManager @@ -51,8 +91,8 @@ namespace Progress { public: virtual bool StatusChanged(std::string PackageName, unsigned int StepsDone, - unsigned int TotalSteps); - + unsigned int TotalSteps, + std::string HumanReadableAction); }; diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index 8c0d2e855..32bc5284e 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -1032,28 +1032,32 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() // PM::DoInstallPostFork - Does install part that happens after the fork /*{{{*/ // --------------------------------------------------------------------- pkgPackageManager::OrderResult -pkgPackageManager::DoInstallPostFork(int statusFd) +pkgPackageManager::DoInstallPostFork(APT::Progress::PackageManager *progress) { +// FIXME: port to new structure +#if 0 if(statusFd > 0) // FIXME: use SetCloseExec here once it taught about throwing // exceptions instead of doing _exit(100) on failure fcntl(statusFd,F_SETFD,FD_CLOEXEC); - bool goResult = Go(statusFd); +#endif + bool goResult = Go(progress); if(goResult == false) return Failed; return Res; }; - + /*}}}*/ // PM::DoInstall - Does the installation /*{{{*/ // --------------------------------------------------------------------- /* This uses the filenames in FileNames and the information in the DepCache to perform the installation of packages.*/ -pkgPackageManager::OrderResult pkgPackageManager::DoInstall(int statusFd) +pkgPackageManager::OrderResult +pkgPackageManager::DoInstall(APT::Progress::PackageManager *progress) { if(DoInstallPreFork() == Failed) return Failed; - return DoInstallPostFork(statusFd); + return DoInstallPostFork(progress); } /*}}}*/ diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index 4956e816f..5c15ac0e4 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -24,6 +24,7 @@ #define PKGLIB_PACKAGEMANAGER_H #include +#include #include #include @@ -40,6 +41,7 @@ class pkgSourceList; class pkgOrderList; class pkgRecords; + class pkgPackageManager : protected pkgCache::Namespace { public: @@ -84,7 +86,7 @@ class pkgPackageManager : protected pkgCache::Namespace virtual bool Install(PkgIterator /*Pkg*/,std::string /*File*/) {return false;}; virtual bool Configure(PkgIterator /*Pkg*/) {return false;}; virtual bool Remove(PkgIterator /*Pkg*/,bool /*Purge*/=false) {return false;}; - virtual bool Go(int statusFd=-1) {return true;}; + virtual bool Go(APT::Progress::PackageManager *progress) {return true;}; virtual void Reset() {}; // the result of the operation @@ -97,7 +99,17 @@ class pkgPackageManager : protected pkgCache::Namespace pkgRecords *Recs); // Do the installation - OrderResult DoInstall(int statusFd=-1); + OrderResult DoInstall(APT::Progress::PackageManager *progress); + + // compat + OrderResult DoInstall(int statusFd=-1) { + APT::Progress::PackageManager *progress = new + APT::Progress::PackageManagerProgressFd(statusFd); + OrderResult res = DoInstall(progress); + delete progress; + return res; + } + // stuff that needs to be done before the fork() of a library that // uses apt @@ -107,7 +119,7 @@ class pkgPackageManager : protected pkgCache::Namespace }; // stuff that needs to be done after the fork - OrderResult DoInstallPostFork(int statusFd=-1); + OrderResult DoInstallPostFork(APT::Progress::PackageManager *progress); bool FixMissing(); /** \brief returns all packages dpkg let disappear */ -- cgit v1.2.3 From ca5b257835578d98145becbc3d97505394a7726c Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sun, 13 Oct 2013 15:10:53 +0200 Subject: add APT::Progress::PackageManager::Pulse() --- apt-pkg/deb/dpkgpm.cc | 5 +++-- apt-pkg/iprogress.h | 7 ++++++- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 0c3be4ce5..d617a3c0c 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1364,13 +1364,14 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) FD_SET(_dpkgin, &rfds); if(master >= 0) FD_SET(master, &rfds); - tv.tv_sec = 1; - tv.tv_nsec = 0; + tv.tv_sec = 0; + tv.tv_nsec = d->progress->GetPulseInterval(); select_ret = pselect(max(master, _dpkgin)+1, &rfds, NULL, NULL, &tv, &original_sigmask); if (select_ret < 0 && (errno == EINVAL || errno == ENOSYS)) select_ret = racy_pselect(max(master, _dpkgin)+1, &rfds, NULL, NULL, &tv, &original_sigmask); + d->progress->Pulse(); if (select_ret == 0) continue; else if (select_ret < 0 && errno == EINTR) diff --git a/apt-pkg/iprogress.h b/apt-pkg/iprogress.h index 6519e9445..04520ffe8 100644 --- a/apt-pkg/iprogress.h +++ b/apt-pkg/iprogress.h @@ -28,7 +28,12 @@ namespace Progress { virtual void Finished() {}; virtual pid_t fork() {return fork(); }; - + + virtual void Pulse() {}; + virtual long GetPulseInterval() { + return 500000; + }; + virtual bool StatusChanged(std::string PackageName, unsigned int StepsDone, unsigned int TotalSteps, -- cgit v1.2.3 From f9935b1c33203b9e47ca0ff5cb441c7963b19fbc Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 14 Oct 2013 07:40:56 +0200 Subject: refactor writing to WriteToStatusFd() --- apt-pkg/iprogress.cc | 30 ++++++++++++++++-------------- apt-pkg/iprogress.h | 3 +++ 2 files changed, 19 insertions(+), 14 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/iprogress.cc b/apt-pkg/iprogress.cc index 6c5d33d4a..7d1cc6341 100644 --- a/apt-pkg/iprogress.cc +++ b/apt-pkg/iprogress.cc @@ -33,19 +33,24 @@ PackageManagerProgressFd::PackageManagerProgressFd(int progress_fd) OutStatusFd = progress_fd; } +void PackageManagerProgressFd::WriteToStatusFd(std::string s) +{ + if(OutStatusFd <= 0) + return; + FileFd::Write(OutStatusFd, s.c_str(), s.size()); +} + void PackageManagerProgressFd::Started() { _config->Set("APT::Keep-Fds::", OutStatusFd); // send status information that we are about to fork dpkg - if(OutStatusFd > 0) { - std::ostringstream status; - status << "pmstatus:dpkg-exec:" - << (StepsDone/float(StepsTotal)*100.0) - << ":" << _("Running dpkg") - << std::endl; - FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); - } + std::ostringstream status; + status << "pmstatus:dpkg-exec:" + << (StepsDone/float(StepsTotal)*100.0) + << ":" << _("Running dpkg") + << std::endl; + WriteToStatusFd(status.str()); } void PackageManagerProgressFd::Finished() @@ -64,8 +69,7 @@ void PackageManagerProgressFd::Error(std::string PackageName, << ":" << (StepsDone/float(TotalSteps)*100.0) << ":" << ErrorMessage << std::endl; - if(OutStatusFd > 0) - FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); + WriteToStatusFd(status.str()); } void PackageManagerProgressFd::ConffilePrompt(std::string PackageName, @@ -78,8 +82,7 @@ void PackageManagerProgressFd::ConffilePrompt(std::string PackageName, << ":" << (StepsDone/float(TotalSteps)*100.0) << ":" << ConfMessage << std::endl; - if(OutStatusFd > 0) - FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); + WriteToStatusFd(status.str()); } @@ -97,8 +100,7 @@ bool PackageManagerProgressFd::StatusChanged(std::string PackageName, << ":" << (StepsDone/float(StepsTotal)*100.0) << ":" << pkg_action << std::endl; - if(OutStatusFd > 0) - FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); + WriteToStatusFd(status.str()); return true; } diff --git a/apt-pkg/iprogress.h b/apt-pkg/iprogress.h index 04520ffe8..5584b3940 100644 --- a/apt-pkg/iprogress.h +++ b/apt-pkg/iprogress.h @@ -54,9 +54,12 @@ namespace Progress { int OutStatusFd; int StepsDone; int StepsTotal; + void WriteToStatusFd(std::string msg); public: PackageManagerProgressFd(int progress_fd); + + // FIXME: rename to Start/Stop to match the pkgAcquireStatus virtual void Started(); virtual void Finished(); -- cgit v1.2.3 From a22fdebf63a42026e4350ebd069512c797bc2a5b Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 14 Oct 2013 07:52:21 +0200 Subject: rename APT::Progress::Packagemanager Started->Start, Finished->Stop to match pkgAcquireStatus --- apt-pkg/deb/dpkgpm.cc | 10 ++++------ apt-pkg/iprogress.cc | 8 ++++---- apt-pkg/iprogress.h | 13 ++++++------- 3 files changed, 14 insertions(+), 17 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index d617a3c0c..36d8c829a 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1264,11 +1264,9 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) _error->DumpErrors(std::cerr); _error->RevertToStack(); - // Fork dpkg - pid_t Child; - d->progress->Started(); - - Child = ExecFork(); + // Tell the progress that its starting and fork dpkg + d->progress->Start(); + pid_t Child = ExecFork(); // This is the child if (Child == 0) { @@ -1398,7 +1396,7 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) signal(SIGHUP,old_SIGHUP); // tell the progress - d->progress->Finished(); + d->progress->Stop(); if(master >= 0) { diff --git a/apt-pkg/iprogress.cc b/apt-pkg/iprogress.cc index 7d1cc6341..7de190da0 100644 --- a/apt-pkg/iprogress.cc +++ b/apt-pkg/iprogress.cc @@ -40,7 +40,7 @@ void PackageManagerProgressFd::WriteToStatusFd(std::string s) FileFd::Write(OutStatusFd, s.c_str(), s.size()); } -void PackageManagerProgressFd::Started() +void PackageManagerProgressFd::Start() { _config->Set("APT::Keep-Fds::", OutStatusFd); @@ -53,7 +53,7 @@ void PackageManagerProgressFd::Started() WriteToStatusFd(status.str()); } -void PackageManagerProgressFd::Finished() +void PackageManagerProgressFd::Stop() { // clear the Keep-Fd again _config->Clear("APT::Keep-Fds", OutStatusFd); @@ -134,13 +134,13 @@ PackageManagerFancy::PackageManagerFancy() } } -void PackageManagerFancy::Started() +void PackageManagerFancy::Start() { if (nr_terminal_rows > 0) SetupTerminalScrollArea(nr_terminal_rows); } -void PackageManagerFancy::Finished() +void PackageManagerFancy::Stop() { if (nr_terminal_rows > 0) { diff --git a/apt-pkg/iprogress.h b/apt-pkg/iprogress.h index 5584b3940..ccf154279 100644 --- a/apt-pkg/iprogress.h +++ b/apt-pkg/iprogress.h @@ -24,8 +24,8 @@ namespace Progress { : percentage(0.0), last_reported_progress(0) {}; virtual ~PackageManager() {}; - virtual void Started() {}; - virtual void Finished() {}; + virtual void Start() {}; + virtual void Stop() {}; virtual pid_t fork() {return fork(); }; @@ -59,9 +59,8 @@ namespace Progress { public: PackageManagerProgressFd(int progress_fd); - // FIXME: rename to Start/Stop to match the pkgAcquireStatus - virtual void Started(); - virtual void Finished(); + virtual void Start(); + virtual void Stop(); virtual bool StatusChanged(std::string PackageName, unsigned int StepsDone, @@ -86,8 +85,8 @@ namespace Progress { public: PackageManagerFancy(); - virtual void Started(); - virtual void Finished(); + virtual void Start(); + virtual void Stop(); virtual bool StatusChanged(std::string PackageName, unsigned int StepsDone, unsigned int TotalSteps, -- cgit v1.2.3 From 5e9458e285af11c7fa4308add10d250e3546c8bf Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 14 Oct 2013 08:42:48 +0200 Subject: re-add APT::Keep-Fds:: for the dpkg status-fd in dpkgpm.cc as we always need this --- apt-pkg/deb/dpkgpm.cc | 6 ++++++ apt-pkg/iprogress.cc | 9 +++++++-- apt-pkg/packagemanager.cc | 18 +++++------------- 3 files changed, 18 insertions(+), 15 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 36d8c829a..fbb5e4c96 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1264,6 +1264,9 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) _error->DumpErrors(std::cerr); _error->RevertToStack(); + // this is the dpkg status-fd, we need to keep it + _config->Set("APT::Keep-Fds::",fd[1]); + // Tell the progress that its starting and fork dpkg d->progress->Start(); pid_t Child = ExecFork(); @@ -1316,6 +1319,9 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) if (_config->FindB("DPkg::UseIoNice", false) == true) ionice(Child); + // clear the Keep-Fd again + _config->Clear("APT::Keep-Fds",fd[1]); + // Wait for dpkg int Status = 0; diff --git a/apt-pkg/iprogress.cc b/apt-pkg/iprogress.cc index 7de190da0..bed991d68 100644 --- a/apt-pkg/iprogress.cc +++ b/apt-pkg/iprogress.cc @@ -8,7 +8,7 @@ #include #include #include - +#include namespace APT { namespace Progress { @@ -42,7 +42,12 @@ void PackageManagerProgressFd::WriteToStatusFd(std::string s) void PackageManagerProgressFd::Start() { - _config->Set("APT::Keep-Fds::", OutStatusFd); + if(OutStatusFd <= 0) + return; + + // FIXME: use SetCloseExec here once it taught about throwing + // exceptions instead of doing _exit(100) on failure + fcntl(OutStatusFd,F_SETFD,FD_CLOEXEC); // send status information that we are about to fork dpkg std::ostringstream status; diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index 32bc5284e..3690a64c3 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -26,7 +26,6 @@ #include #include -#include #include /*}}}*/ @@ -1034,18 +1033,11 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() pkgPackageManager::OrderResult pkgPackageManager::DoInstallPostFork(APT::Progress::PackageManager *progress) { -// FIXME: port to new structure -#if 0 - if(statusFd > 0) - // FIXME: use SetCloseExec here once it taught about throwing - // exceptions instead of doing _exit(100) on failure - fcntl(statusFd,F_SETFD,FD_CLOEXEC); -#endif - bool goResult = Go(progress); - if(goResult == false) - return Failed; - - return Res; + bool goResult = Go(progress); + if(goResult == false) + return Failed; + + return Res; }; /*}}}*/ // PM::DoInstall - Does the installation /*{{{*/ -- cgit v1.2.3 From 7794a6880e74446075d9cae19525829ada5b0d91 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 13 Oct 2013 19:33:09 +0200 Subject: fix progress-segfault in case of dpkg errors/prompts Errors and conffile prompts have a fourth information piece, which the "old" code access which isn't provided by the "new" one. This isn't checking if the messages are really well-formed, so it could still segfault on misformed messages, but this code needs more work anyway, so one step at a time. Closes: 726047 --- apt-pkg/deb/dpkgpm.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index c29d21574..1fbeabbdc 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -546,8 +546,8 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) // A dpkg error message may contain additional ":" (like // "failed in buffer_write(fd) (10, ret=-1): backend dpkg-deb ..." // so we need to ensure to not split too much - std::vector list = StringSplit(line, ": ", 3); - if(list.size() != 3) + std::vector list = StringSplit(line, ": ", 4); + if(list.size() < 3) { if (Debug == true) std::clog << "ignoring line: not enough ':'" << std::endl; -- cgit v1.2.3 From fd6417a6026401f95af82608e12b4a9d105b090f Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 15 Oct 2013 15:39:59 +0200 Subject: fix logic for finding what package dpkg means in the --status-fd and only send out short packagenames --- apt-pkg/deb/dpkgpm.cc | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index b4d812d26..61d8eec02 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -557,11 +557,26 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) std::string pkgname = list[1]; if (pkgname.find(":") == std::string::npos) { - string const nativeArch = _config->Find("APT::Architecture"); - pkgname = pkgname + ":" + nativeArch; + // find the package in the group that is in a touched by dpkg + // if there are multiple dpkg will send us a full pkgname:arch + pkgCache::GrpIterator Grp = Cache.FindGrp(pkgname); + if (Grp.end() == false) + { + pkgCache::PkgIterator P = Grp.PackageList(); + for (; P.end() != true; P = Grp.NextPkg(P)) + { + if(Cache[P].Mode != pkgDepCache::ModeKeep) + { + pkgname = P.FullName(); + break; + } + } + } } const char* const pkg = pkgname.c_str(); const char* action = list[2].c_str(); + + std::string short_pkgname = StringSplit(pkgname, ":")[0]; // 'processing' from dpkg looks like // 'processing: action: pkg' @@ -640,7 +655,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) PackageOpsDone[pkg]++; PackagesDone++; // build the status str - status << "pmstatus:" << pkg + status << "pmstatus:" << short_pkgname << ":" << (PackagesDone/float(PackagesTotal)*100.0) << ":" << s << endl; @@ -653,7 +668,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) std::clog << "send: '" << status.str() << "'" << endl; } if (Debug == true) - std::clog << "(parsed from dpkg) pkg: " << pkg + std::clog << "(parsed from dpkg) pkg: " << short_pkgname << " action: " << action << endl; } /*}}}*/ -- cgit v1.2.3 From 42c1513b712818823e0a136c949f0d93c46907d7 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 15 Oct 2013 18:07:44 +0200 Subject: tests, do not send pkgname with arch via the status-fd --- apt-pkg/deb/dpkgpm.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index d18900b9c..fe38bf697 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -649,7 +649,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) // action const char *translation = _(states[PackageOpsDone[pkg]].str); char s[200]; - snprintf(s, sizeof(s), translation, pkg); + snprintf(s, sizeof(s), translation, short_pkgname.c_str()); // we moved from one dpkg state to a new one, report that PackageOpsDone[pkg]++; -- cgit v1.2.3 From c420fe0096985234e861aaafc2b9908b6259a1bb Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 17 Oct 2013 07:47:15 +0200 Subject: fix broken clean when apt was finished and ensure that terminal progress is updated when a new dpkg-loop is entered in dpkgpm.cc --- apt-pkg/deb/dpkgpm.cc | 28 +++++++++++++++++++--------- apt-pkg/deb/dpkgpm.h | 1 + 2 files changed, 20 insertions(+), 9 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index fe38bf697..f870fab93 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -993,6 +993,20 @@ void pkgDPkgPM::SetupTerminalScrollArea(int nr_rows) std::flush(std::cout); } +void pkgDPkgPM::CleanupTerminal() +{ + // reset scroll area + SetupTerminalScrollArea(d->nr_terminal_rows + 1); + if(d->fancy_progress_output) + { + // override the progress line (sledgehammer) + static const char* clear_screen_below_cursor = "\033[J"; + std::cout << clear_screen_below_cursor; + std::flush(std::cout); + } +} + + // DPkgPM::Go - Run the sequence /*{{{*/ // --------------------------------------------------------------------- /* This globs the operations and calls dpkg @@ -1430,7 +1444,9 @@ bool pkgDPkgPM::Go(int OutStatusFd) if (fcntl(STDIN_FILENO,F_SETFL,Flags & (~(long)O_NONBLOCK)) < 0) _exit(100); } + // setup terminal SetupTerminalScrollArea(d->nr_terminal_rows); + SendTerminalProgress(PackagesDone/float(PackagesTotal)*100.0); /* No Job Control Stop Env is a magic dpkg var that prevents it from using sigstop */ @@ -1525,15 +1541,6 @@ bool pkgDPkgPM::Go(int OutStatusFd) signal(SIGHUP,old_SIGHUP); - // reset scroll area - SetupTerminalScrollArea(d->nr_terminal_rows + 1); - if(d->fancy_progress_output) - { - // override the progress line (sledgehammer) - static const char* clear_screen_below_cursor = "\033[J"; - std::cout << clear_screen_below_cursor; - } - if(master >= 0) { tcsetattr(0, TCSAFLUSH, &tt); @@ -1564,6 +1571,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) if(stopOnError) { CloseLog(); + CleanupTerminal(); return false; } } @@ -1574,6 +1582,8 @@ bool pkgDPkgPM::Go(int OutStatusFd) if(_config->FindB("DPkgPM::Progress", false) == true) SendTerminalProgress(100); + CleanupTerminal(); + if (pkgPackageManager::SigINTStop) _error->Warning(_("Operation was interrupted before it could finish")); diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index 3b8d36623..1a58e1af5 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -87,6 +87,7 @@ class pkgDPkgPM : public pkgPackageManager // Terminal progress void SetupTerminalScrollArea(int nr_scrolled_rows); void SendTerminalProgress(float percentage); + void CleanupTerminal(); // apport integration void WriteApportReport(const char *pkgpath, const char *errormsg); -- cgit v1.2.3 From 7c016f6e107ba55d7b55870166273ce63c4ecb65 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 17 Oct 2013 08:18:09 +0200 Subject: ensure that short-name -> long-name detection for dpkg-status works for reinstalls too --- apt-pkg/deb/dpkgpm.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 1b234c0ed..19de44001 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -561,7 +561,9 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line) pkgCache::PkgIterator P = Grp.PackageList(); for (; P.end() != true; P = Grp.NextPkg(P)) { - if(Cache[P].Mode != pkgDepCache::ModeKeep) + if(Cache[P].Install() || Cache[P].ReInstall() || + Cache[P].Upgrade() || Cache[P].Downgrade() || + Cache[P].Delete() || Cache[P].Purge()) { pkgname = P.FullName(); break; @@ -569,6 +571,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line) } } } + const char* const pkg = pkgname.c_str(); const char* action = list[2].c_str(); -- cgit v1.2.3 From dd640f3cece45693b57b49d90ba7cc4134577070 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 18 Oct 2013 08:02:29 +0200 Subject: cleanup --- apt-pkg/deb/dpkgpm.cc | 104 ++++++++++++++++++++++++++++++++++---------------- apt-pkg/deb/dpkgpm.h | 3 +- apt-pkg/iprogress.cc | 2 +- 3 files changed, 74 insertions(+), 35 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 19de44001..7fba04a30 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -507,6 +507,34 @@ void pkgDPkgPM::DoTerminalPty(int master) fwrite(term_buf, len, sizeof(char), d->term_out); } /*}}}*/ + +std::string pkgDPkgPM::ExpandShortPackageName(pkgDepCache &Cache, + const std::string &short_pkgname) +{ + if (short_pkgname.find(":") != string::npos) + return short_pkgname; + + std::string pkgname = short_pkgname; + // find the package in the group that is in a touched by dpkg + // if there are multiple dpkg will send us a full pkgname:arch + pkgCache::GrpIterator Grp = Cache.FindGrp(pkgname); + if (Grp.end() == false) + { + pkgCache::PkgIterator P = Grp.PackageList(); + for (; P.end() != true; P = Grp.NextPkg(P)) + { + if(Cache[P].Install() || Cache[P].ReInstall() || + Cache[P].Upgrade() || Cache[P].Downgrade() || + Cache[P].Delete() || Cache[P].Purge()) + { + pkgname = P.FullName(); + return pkgname; + } + } + } + return pkgname; +} + // DPkgPM::ProcessDpkgStatusBuf /*{{{*/ // --------------------------------------------------------------------- /* @@ -549,32 +577,35 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line) std::clog << "ignoring line: not enough ':'" << std::endl; return; } - // dpkg does not send always send "pkgname:arch" so we add it here if needed - std::string pkgname = list[1]; - if (pkgname.find(":") == std::string::npos) + + if (list[0] != "processing" && list[0] != "status") { - // find the package in the group that is in a touched by dpkg - // if there are multiple dpkg will send us a full pkgname:arch - pkgCache::GrpIterator Grp = Cache.FindGrp(pkgname); - if (Grp.end() == false) - { - pkgCache::PkgIterator P = Grp.PackageList(); - for (; P.end() != true; P = Grp.NextPkg(P)) - { - if(Cache[P].Install() || Cache[P].ReInstall() || - Cache[P].Upgrade() || Cache[P].Downgrade() || - Cache[P].Delete() || Cache[P].Purge()) - { - pkgname = P.FullName(); - break; - } - } - } + if (Debug == true) + std::clog << "ignoring line: unknown prefix '" << list[0] << "'" + << std::endl; + return; + } + + std::string prefix = list[0]; + std::string pkgname; + std::string action; + if (prefix == "processing") + { + action = list[1]; + pkgname = list[2]; + if (action != "install" && action != "configure" && + action != "remove" && action != "purge" && + action != "disappear") + return; + } else if (prefix == "status") { + pkgname = list[1]; + action = list[2]; } + // dpkg does not always send out the architecture so we need to guess + // it here + pkgname = ExpandShortPackageName(Cache, pkgname); const char* const pkg = pkgname.c_str(); - const char* action = list[2].c_str(); - std::string short_pkgname = StringSplit(pkgname, ":")[0]; std::string i18n_pkgname = short_pkgname; if (pkgname.find(":") != string::npos) @@ -587,48 +618,52 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line) // 'processing: action: pkg' if(strncmp(list[0].c_str(), "processing", strlen("processing")) == 0) { - const char* const pkg_or_trigger = list[2].c_str(); - action = list[1].c_str(); const std::pair * const iter = std::find_if(PackageProcessingOpsBegin, PackageProcessingOpsEnd, - MatchProcessingOp(action)); + MatchProcessingOp(action.c_str())); if(iter == PackageProcessingOpsEnd) { if (Debug == true) std::clog << "ignoring unknown action: " << action << std::endl; return; } + std::string pkg_action; - strprintf(pkg_action, _(iter->second), pkg_or_trigger); + strprintf(pkg_action, _(iter->second), short_pkgname.c_str()); - d->progress->StatusChanged(pkg_or_trigger, PackagesDone, PackagesTotal, + d->progress->StatusChanged(pkgname, PackagesDone, PackagesTotal, pkg_action); - if (strncmp(action, "disappear", strlen("disappear")) == 0) - handleDisappearAction(pkg_or_trigger); + + if (strncmp(action.c_str(), "disappear", strlen("disappear")) == 0) + handleDisappearAction(pkgname); return; } - if(strncmp(action,"error",strlen("error")) == 0) + // FIXME: fix indent once this goes into debian/sid + if(strncmp(prefix.c_str(), "status", strlen("processing")) == 0) + { + + if(strncmp(action.c_str(),"error",strlen("error")) == 0) { d->progress->Error(list[1], PackagesDone, PackagesTotal, list[3]); pkgFailures++; WriteApportReport(list[1].c_str(), list[3].c_str()); return; } - else if(strncmp(action,"conffile",strlen("conffile")) == 0) + else if(strncmp(action.c_str(),"conffile",strlen("conffile")) == 0) { d->progress->ConffilePrompt(list[1], PackagesDone, PackagesTotal, list[3]); return; - } + } else { vector const &states = PackageOps[pkg]; const char *next_action = NULL; if(PackageOpsDone[pkg] < states.size()) next_action = states[PackageOpsDone[pkg]].state; // check if the package moved to the next dpkg state - if(next_action && (strcmp(action, next_action) == 0)) + if(next_action && (strcmp(action.c_str(), next_action) == 0)) { // only read the translation if there is actually a next // action @@ -644,9 +679,12 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line) d->progress->StatusChanged(pkgname, PackagesDone, PackagesTotal, translation); } + if (Debug == true) std::clog << "(parsed from dpkg) pkg: " << pkgname << " action: " << action << endl; + } + } } /*}}}*/ // DPkgPM::handleDisappearAction /*{{{*/ diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index 302507105..922631ba8 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -84,11 +84,12 @@ class pkgDPkgPM : public pkgPackageManager __deprecated bool SendV2Pkgs(FILE *F); bool SendPkgsInfo(FILE * const F, unsigned int const &Version); void WriteHistoryTag(std::string const &tag, std::string value); + std::string ExpandShortPackageName(pkgDepCache &Cache, + const std::string &short_pkgname); // Terminal progress void SetupTerminalScrollArea(int nr_scrolled_rows); void SendTerminalProgress(float percentage); - void CleanupTerminal(); // apport integration void WriteApportReport(const char *pkgpath, const char *errormsg); diff --git a/apt-pkg/iprogress.cc b/apt-pkg/iprogress.cc index bed991d68..318d626d4 100644 --- a/apt-pkg/iprogress.cc +++ b/apt-pkg/iprogress.cc @@ -101,7 +101,7 @@ bool PackageManagerProgressFd::StatusChanged(std::string PackageName, // build the status str std::ostringstream status; - status << "pmstatus:" << PackageName + status << "pmstatus:" << StringSplit(PackageName, ":")[0] << ":" << (StepsDone/float(StepsTotal)*100.0) << ":" << pkg_action << std::endl; -- cgit v1.2.3 From 2842f8f3e31fbec8c53ce40f15ff0c76f021f030 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 18 Oct 2013 08:10:29 +0200 Subject: add APT::String::Strip(), start cleanup of ProcessDpkgStatusLine --- apt-pkg/contrib/strutl.cc | 17 ++++++++++++++++- apt-pkg/contrib/strutl.h | 7 +++++++ apt-pkg/deb/dpkgpm.cc | 33 ++++++++++++++++++++++++++++----- 3 files changed, 51 insertions(+), 6 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 77e48962c..9f794927d 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -36,7 +36,22 @@ using namespace std; /*}}}*/ - +// Strip - Remove white space from the front and back of a string /*{{{*/ +// --------------------------------------------------------------------- +namespace APT { + namespace String { +std::string Strip(const std::string &s) +{ + size_t start = s.find_first_not_of(" \t\n"); + // only whitespace + if (start == string::npos) + return ""; + size_t end = s.find_last_not_of(" \t\n"); + return s.substr(start, end-start+1); +} +} +} + /*}}}*/ // UTF8ToCodeset - Convert some UTF-8 string for some codeset /*{{{*/ // --------------------------------------------------------------------- /* This is handy to use before display some information for enduser */ diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index b42e06491..c8fc317c0 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -33,6 +33,13 @@ using std::vector; using std::ostream; #endif +namespace APT { + namespace String { + std::string Strip(const std::string &s); + }; +}; + + bool UTF8ToCodeset(const char *codeset, const std::string &orig, std::string *dest); char *_strstrip(char *String); char *_strrstrip(char *String); // right strip only diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index f870fab93..c5d40c033 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -540,6 +540,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) 'processing: trigproc: trigger' */ + // we need to split on ": " (note the appended space) as the ':' is // part of the pkgname:arch information that dpkg sends // @@ -553,8 +554,26 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) std::clog << "ignoring line: not enough ':'" << std::endl; return; } + + std::string prefix = APT::String::Strip(list[0]); + std::string pkgname; + std::string action_str; + if (prefix == "processing") + { + pkgname = APT::String::Strip(list[2]); + action_str = APT::String::Strip(list[1]); + } + else if (prefix == "status") + { + pkgname = APT::String::Strip(list[1]); + action_str = APT::String::Strip(list[2]); + } else { + if (Debug == true) + std::clog << "unknown prefix '" << prefix << "'" << std::endl; + return; + } + // dpkg does not send always send "pkgname:arch" so we add it here if needed - std::string pkgname = list[1]; if (pkgname.find(":") == std::string::npos) { // find the package in the group that is in a touched by dpkg @@ -574,13 +593,12 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) } } const char* const pkg = pkgname.c_str(); - const char* action = list[2].c_str(); - + const char* action = action_str.c_str(); std::string short_pkgname = StringSplit(pkgname, ":")[0]; // 'processing' from dpkg looks like // 'processing: action: pkg' - if(strncmp(list[0].c_str(), "processing", strlen("processing")) == 0) + if(prefix == "processing") { char s[200]; const char* const pkg_or_trigger = list[2].c_str(); @@ -609,7 +627,11 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) if (strncmp(action, "disappear", strlen("disappear")) == 0) handleDisappearAction(pkg_or_trigger); return; - } + } + + // FIXME: fix indent once the progress-refactor branch is merged + if (prefix == "status") + { if(strncmp(action,"error",strlen("error")) == 0) { @@ -670,6 +692,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) if (Debug == true) std::clog << "(parsed from dpkg) pkg: " << short_pkgname << " action: " << action << endl; + } } /*}}}*/ // DPkgPM::handleDisappearAction /*{{{*/ -- cgit v1.2.3 From 11ef54810d6241b6d2433d27099b43763dabaee3 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 18 Oct 2013 08:32:36 +0200 Subject: reshuffle dpkgpm.cc code a bit more --- apt-pkg/deb/dpkgpm.cc | 68 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 28 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index c5d40c033..41885e6e8 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -555,6 +555,8 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) return; } + // build the (prefix, pkgname, action) tuple, position of this + // is different for "processing" or "status" messages std::string prefix = APT::String::Strip(list[0]); std::string pkgname; std::string action_str; @@ -573,6 +575,38 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) return; } + // FIXME: fix indent once the progress-refactor branch is merged + if (prefix == "status") + { + + if(action_str == "error") + { + status << "pmerror:" << list[1] + << ":" << (PackagesDone/float(PackagesTotal)*100.0) + << ":" << list[3] + << endl; + if(OutStatusFd > 0) + FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); + if (Debug == true) + std::clog << "send: '" << status.str() << "'" << endl; + pkgFailures++; + WriteApportReport(list[1].c_str(), list[3].c_str()); + return; + } + else if(action_str == "conffile") + { + status << "pmconffile:" << list[1] + << ":" << (PackagesDone/float(PackagesTotal)*100.0) + << ":" << list[3] + << endl; + if(OutStatusFd > 0) + FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); + if (Debug == true) + std::clog << "send: '" << status.str() << "'" << endl; + return; + } + } + // dpkg does not send always send "pkgname:arch" so we add it here if needed if (pkgname.find(":") == std::string::npos) { @@ -595,6 +629,12 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) const char* const pkg = pkgname.c_str(); const char* action = action_str.c_str(); std::string short_pkgname = StringSplit(pkgname, ":")[0]; + std::string arch = ""; + if (pkgname.find(":") != string::npos) + arch = StringSplit(pkgname, ":")[1]; + std::string i18n_pkgname = pkgname; + if (arch.size() != 0) + strprintf(i18n_pkgname, "%s (%s)", short_pkgname.c_str(), arch.c_str()); // 'processing' from dpkg looks like // 'processing: action: pkg' @@ -629,37 +669,9 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) return; } - // FIXME: fix indent once the progress-refactor branch is merged if (prefix == "status") { - if(strncmp(action,"error",strlen("error")) == 0) - { - status << "pmerror:" << list[1] - << ":" << (PackagesDone/float(PackagesTotal)*100.0) - << ":" << list[3] - << endl; - if(OutStatusFd > 0) - FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); - if (Debug == true) - std::clog << "send: '" << status.str() << "'" << endl; - pkgFailures++; - WriteApportReport(list[1].c_str(), list[3].c_str()); - return; - } - else if(strncmp(action,"conffile",strlen("conffile")) == 0) - { - status << "pmconffile:" << list[1] - << ":" << (PackagesDone/float(PackagesTotal)*100.0) - << ":" << list[3] - << endl; - if(OutStatusFd > 0) - FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); - if (Debug == true) - std::clog << "send: '" << status.str() << "'" << endl; - return; - } - vector const &states = PackageOps[pkg]; const char *next_action = NULL; if(PackageOpsDone[pkg] < states.size()) -- cgit v1.2.3 From 27ede340880968cad79b5cc675f283480eb046f4 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 18 Oct 2013 09:28:08 +0200 Subject: reshuffle the pkgDPkgPM::ProcessDpkgStatusLine() some more to make it more robust --- apt-pkg/deb/dpkgpm.cc | 168 +++++++++++++++++++++++++++----------------------- 1 file changed, 91 insertions(+), 77 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 41885e6e8..b5d314165 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -516,29 +516,15 @@ void pkgDPkgPM::DoTerminalPty(int master) void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) { bool const Debug = _config->FindB("Debug::pkgDPkgProgressReporting",false); - // the status we output - ostringstream status; - if (Debug == true) std::clog << "got from dpkg '" << line << "'" << std::endl; - /* dpkg sends strings like this: 'status: : ' 'status: :: ' - errors look like this: - 'status: /var/cache/apt/archives/krecipes_0.8.1-0ubuntu1_i386.deb : error : trying to overwrite `/usr/share/doc/kde/HTML/en/krecipes/krectip.png', which is also in package krecipes-data - and conffile-prompt like this - 'status: conffile-prompt: conffile : 'current-conffile' 'new-conffile' useredited distedited - Newer versions of dpkg sent also: - 'processing: install: pkg' - 'processing: configure: pkg' - 'processing: remove: pkg' - 'processing: purge: pkg' - 'processing: disappear: pkg' - 'processing: trigproc: trigger' - + 'processing: {install,configure,remove,purge,disappear,trigproc}: pkg' + 'processing: {install,configure,remove,purge,disappear,trigproc}: trigger' */ // we need to split on ": " (note the appended space) as the ':' is @@ -560,11 +546,30 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) std::string prefix = APT::String::Strip(list[0]); std::string pkgname; std::string action_str; + ostringstream status; + + // "processing" has the form "processing: action: pkg or trigger" + // with action = ["install", "configure", "remove", "purge", "disappear", + // "trigproc"] if (prefix == "processing") { pkgname = APT::String::Strip(list[2]); action_str = APT::String::Strip(list[1]); + + // this is what we support in the processing stage + if(action_str != "install" && action_str != "configure" && + action_str != "remove" && action_str != "purge" && + action_str != "purge") + { + if (Debug == true) + std::clog << "ignoring processing action: '" << action_str + << "'" << std::endl; + return; + } } + // "status" has the form: "status: pkg: state" + // with state in ["half-installed", "unpacked", "half-configured", + // "installed", "config-files", "not-installed"] else if (prefix == "status") { pkgname = APT::String::Strip(list[1]); @@ -575,38 +580,47 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) return; } - // FIXME: fix indent once the progress-refactor branch is merged - if (prefix == "status") - { - if(action_str == "error") - { - status << "pmerror:" << list[1] - << ":" << (PackagesDone/float(PackagesTotal)*100.0) - << ":" << list[3] - << endl; - if(OutStatusFd > 0) - FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); - if (Debug == true) - std::clog << "send: '" << status.str() << "'" << endl; - pkgFailures++; - WriteApportReport(list[1].c_str(), list[3].c_str()); - return; - } - else if(action_str == "conffile") + /* handle the special cases first: + + errors look like this: + 'status: /var/cache/apt/archives/krecipes_0.8.1-0ubuntu1_i386.deb : error : trying to overwrite `/usr/share/doc/kde/HTML/en/krecipes/krectip.png', which is also in package krecipes-data + and conffile-prompt like this + 'status: conffile-prompt: conffile : 'current-conffile' 'new-conffile' useredited distedited + */ + if (prefix == "status") { - status << "pmconffile:" << list[1] - << ":" << (PackagesDone/float(PackagesTotal)*100.0) - << ":" << list[3] - << endl; - if(OutStatusFd > 0) - FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); - if (Debug == true) - std::clog << "send: '" << status.str() << "'" << endl; - return; - } + if(action_str == "error") + { + status << "pmerror:" << list[1] + << ":" << (PackagesDone/float(PackagesTotal)*100.0) + << ":" << list[3] + << endl; + if(OutStatusFd > 0) + FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); + if (Debug == true) + std::clog << "send: '" << status.str() << "'" << endl; + pkgFailures++; + WriteApportReport(list[1].c_str(), list[3].c_str()); + return; + } + else if(action_str == "conffile") + { + status << "pmconffile:" << list[1] + << ":" << (PackagesDone/float(PackagesTotal)*100.0) + << ":" << list[3] + << endl; + if(OutStatusFd > 0) + FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); + if (Debug == true) + std::clog << "send: '" << status.str() << "'" << endl; + return; + } } + // at this point we know that we should have a valid pkgname, so build all + // the info from it + // dpkg does not send always send "pkgname:arch" so we add it here if needed if (pkgname.find(":") == std::string::npos) { @@ -626,6 +640,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) } } } + const char* const pkg = pkgname.c_str(); const char* action = action_str.c_str(); std::string short_pkgname = StringSplit(pkgname, ":")[0]; @@ -671,39 +686,38 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) if (prefix == "status") { - - vector const &states = PackageOps[pkg]; - const char *next_action = NULL; - if(PackageOpsDone[pkg] < states.size()) - next_action = states[PackageOpsDone[pkg]].state; - // check if the package moved to the next dpkg state - if(next_action && (strcmp(action, next_action) == 0)) - { - // only read the translation if there is actually a next - // action - const char *translation = _(states[PackageOpsDone[pkg]].str); - char s[200]; - snprintf(s, sizeof(s), translation, short_pkgname.c_str()); - - // we moved from one dpkg state to a new one, report that - PackageOpsDone[pkg]++; - PackagesDone++; - // build the status str - status << "pmstatus:" << short_pkgname - << ":" << (PackagesDone/float(PackagesTotal)*100.0) - << ":" << s - << endl; - if(_config->FindB("DPkgPM::Progress", false) == true) - SendTerminalProgress(PackagesDone/float(PackagesTotal)*100.0); - - if(OutStatusFd > 0) - FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); - if (Debug == true) - std::clog << "send: '" << status.str() << "'" << endl; - } - if (Debug == true) - std::clog << "(parsed from dpkg) pkg: " << short_pkgname - << " action: " << action << endl; + vector const &states = PackageOps[pkg]; + const char *next_action = NULL; + if(PackageOpsDone[pkg] < states.size()) + next_action = states[PackageOpsDone[pkg]].state; + // check if the package moved to the next dpkg state + if(next_action && (strcmp(action, next_action) == 0)) + { + // only read the translation if there is actually a next + // action + const char *translation = _(states[PackageOpsDone[pkg]].str); + char s[200]; + snprintf(s, sizeof(s), translation, short_pkgname.c_str()); + + // we moved from one dpkg state to a new one, report that + PackageOpsDone[pkg]++; + PackagesDone++; + // build the status str + status << "pmstatus:" << short_pkgname + << ":" << (PackagesDone/float(PackagesTotal)*100.0) + << ":" << s + << endl; + if(_config->FindB("DPkgPM::Progress", false) == true) + SendTerminalProgress(PackagesDone/float(PackagesTotal)*100.0); + + if(OutStatusFd > 0) + FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); + if (Debug == true) + std::clog << "send: '" << status.str() << "'" << endl; + } + if (Debug == true) + std::clog << "(parsed from dpkg) pkg: " << short_pkgname + << " action: " << action << endl; } } /*}}}*/ -- cgit v1.2.3 From fa300ed15fc5a1d9e146c85d45f0a88b1d7f96bf Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 18 Oct 2013 09:40:05 +0200 Subject: use std::string instead of char* in pkgDPkgPM::ProcessDpkgStatusLine() --- apt-pkg/deb/dpkgpm.cc | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index b5d314165..0ebd9f28b 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -545,7 +545,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) // is different for "processing" or "status" messages std::string prefix = APT::String::Strip(list[0]); std::string pkgname; - std::string action_str; + std::string action; ostringstream status; // "processing" has the form "processing: action: pkg or trigger" @@ -554,15 +554,14 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) if (prefix == "processing") { pkgname = APT::String::Strip(list[2]); - action_str = APT::String::Strip(list[1]); + action = APT::String::Strip(list[1]); // this is what we support in the processing stage - if(action_str != "install" && action_str != "configure" && - action_str != "remove" && action_str != "purge" && - action_str != "purge") + if(action != "install" && action != "configure" && + action != "remove" && action != "purge" && action != "purge") { if (Debug == true) - std::clog << "ignoring processing action: '" << action_str + std::clog << "ignoring processing action: '" << action << "'" << std::endl; return; } @@ -573,7 +572,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) else if (prefix == "status") { pkgname = APT::String::Strip(list[1]); - action_str = APT::String::Strip(list[2]); + action = APT::String::Strip(list[2]); } else { if (Debug == true) std::clog << "unknown prefix '" << prefix << "'" << std::endl; @@ -590,7 +589,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) */ if (prefix == "status") { - if(action_str == "error") + if(action == "error") { status << "pmerror:" << list[1] << ":" << (PackagesDone/float(PackagesTotal)*100.0) @@ -604,7 +603,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) WriteApportReport(list[1].c_str(), list[3].c_str()); return; } - else if(action_str == "conffile") + else if(action == "conffile") { status << "pmconffile:" << list[1] << ":" << (PackagesDone/float(PackagesTotal)*100.0) @@ -621,7 +620,8 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) // at this point we know that we should have a valid pkgname, so build all // the info from it - // dpkg does not send always send "pkgname:arch" so we add it here if needed + // dpkg does not send always send "pkgname:arch" so we add it here + // if needed if (pkgname.find(":") == std::string::npos) { // find the package in the group that is in a touched by dpkg @@ -642,7 +642,6 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) } const char* const pkg = pkgname.c_str(); - const char* action = action_str.c_str(); std::string short_pkgname = StringSplit(pkgname, ":")[0]; std::string arch = ""; if (pkgname.find(":") != string::npos) @@ -655,32 +654,33 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) // 'processing: action: pkg' if(prefix == "processing") { - char s[200]; - const char* const pkg_or_trigger = list[2].c_str(); - action = list[1].c_str(); const std::pair * const iter = std::find_if(PackageProcessingOpsBegin, PackageProcessingOpsEnd, - MatchProcessingOp(action)); + MatchProcessingOp(action.c_str())); if(iter == PackageProcessingOpsEnd) { if (Debug == true) std::clog << "ignoring unknown action: " << action << std::endl; return; } - snprintf(s, sizeof(s), _(iter->second), pkg_or_trigger); + std::string msg; + strprintf(msg, _(iter->second), short_pkgname.c_str()); - status << "pmstatus:" << pkg_or_trigger + status << "pmstatus:" << short_pkgname << ":" << (PackagesDone/float(PackagesTotal)*100.0) - << ":" << s + << ":" << msg << endl; if(OutStatusFd > 0) FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); if (Debug == true) std::clog << "send: '" << status.str() << "'" << endl; - if (strncmp(action, "disappear", strlen("disappear")) == 0) - handleDisappearAction(pkg_or_trigger); + // FIXME: this needs a muliarch testcase + // FIXME2: is "pkgname" here reliable with dpkg only sending us + // short pkgnames? + if (action == "disappear") + handleDisappearAction(pkgname); return; } @@ -691,13 +691,13 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) if(PackageOpsDone[pkg] < states.size()) next_action = states[PackageOpsDone[pkg]].state; // check if the package moved to the next dpkg state - if(next_action && (strcmp(action, next_action) == 0)) + if(next_action && (action == next_action)) { // only read the translation if there is actually a next // action const char *translation = _(states[PackageOpsDone[pkg]].str); - char s[200]; - snprintf(s, sizeof(s), translation, short_pkgname.c_str()); + std::string msg; + strprintf(msg, translation, short_pkgname.c_str()); // we moved from one dpkg state to a new one, report that PackageOpsDone[pkg]++; @@ -705,7 +705,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) // build the status str status << "pmstatus:" << short_pkgname << ":" << (PackagesDone/float(PackagesTotal)*100.0) - << ":" << s + << ":" << msg << endl; if(_config->FindB("DPkgPM::Progress", false) == true) SendTerminalProgress(PackagesDone/float(PackagesTotal)*100.0); -- cgit v1.2.3 From 34d6563ef47b455b69a7bc9ad0838902bb911dea Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 18 Oct 2013 15:56:06 +0200 Subject: merged debian/sid --- apt-pkg/deb/dpkgpm.cc | 257 +++++++++++++++++++++++++------------------------- 1 file changed, 127 insertions(+), 130 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 7fba04a30..b5f858022 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -55,14 +55,13 @@ class pkgDPkgPMPrivate public: pkgDPkgPMPrivate() : stdin_is_dev_null(false), dpkgbuf_pos(0), term_out(NULL), history_out(NULL), - last_reported_progress(0.0), progress(NULL) + progress(NULL) { dpkgbuf[0] = '\0'; } ~pkgDPkgPMPrivate() { } - bool stdin_is_dev_null; // the buffer we use for the dpkg status-fd reading char dpkgbuf[1024]; @@ -70,8 +69,6 @@ public: FILE *term_out; FILE *history_out; string dpkg_error; - - float last_reported_progress; APT::Progress::PackageManager *progress; }; @@ -507,34 +504,6 @@ void pkgDPkgPM::DoTerminalPty(int master) fwrite(term_buf, len, sizeof(char), d->term_out); } /*}}}*/ - -std::string pkgDPkgPM::ExpandShortPackageName(pkgDepCache &Cache, - const std::string &short_pkgname) -{ - if (short_pkgname.find(":") != string::npos) - return short_pkgname; - - std::string pkgname = short_pkgname; - // find the package in the group that is in a touched by dpkg - // if there are multiple dpkg will send us a full pkgname:arch - pkgCache::GrpIterator Grp = Cache.FindGrp(pkgname); - if (Grp.end() == false) - { - pkgCache::PkgIterator P = Grp.PackageList(); - for (; P.end() != true; P = Grp.NextPkg(P)) - { - if(Cache[P].Install() || Cache[P].ReInstall() || - Cache[P].Upgrade() || Cache[P].Downgrade() || - Cache[P].Delete() || Cache[P].Purge()) - { - pkgname = P.FullName(); - return pkgname; - } - } - } - return pkgname; -} - // DPkgPM::ProcessDpkgStatusBuf /*{{{*/ // --------------------------------------------------------------------- /* @@ -542,28 +511,17 @@ std::string pkgDPkgPM::ExpandShortPackageName(pkgDepCache &Cache, void pkgDPkgPM::ProcessDpkgStatusLine(char *line) { bool const Debug = _config->FindB("Debug::pkgDPkgProgressReporting",false); - if (Debug == true) std::clog << "got from dpkg '" << line << "'" << std::endl; - /* dpkg sends strings like this: 'status: : ' 'status: :: ' - errors look like this: - 'status: /var/cache/apt/archives/krecipes_0.8.1-0ubuntu1_i386.deb : error : trying to overwrite `/usr/share/doc/kde/HTML/en/krecipes/krectip.png', which is also in package krecipes-data - and conffile-prompt like this - 'status: conffile-prompt: conffile : 'current-conffile' 'new-conffile' useredited distedited - Newer versions of dpkg sent also: - 'processing: install: pkg' - 'processing: configure: pkg' - 'processing: remove: pkg' - 'processing: purge: pkg' - 'processing: disappear: pkg' - 'processing: trigproc: trigger' - + 'processing: {install,configure,remove,purge,disappear,trigproc}: pkg' + 'processing: {install,configure,remove,purge,disappear,trigproc}: trigger' */ + // we need to split on ": " (note the appended space) as the ':' is // part of the pkgname:arch information that dpkg sends // @@ -578,45 +536,106 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line) return; } - if (list[0] != "processing" && list[0] != "status") + // build the (prefix, pkgname, action) tuple, position of this + // is different for "processing" or "status" messages + std::string prefix = APT::String::Strip(list[0]); + std::string pkgname; + std::string action; + ostringstream status; + + // "processing" has the form "processing: action: pkg or trigger" + // with action = ["install", "configure", "remove", "purge", "disappear", + // "trigproc"] + if (prefix == "processing") + { + pkgname = APT::String::Strip(list[2]); + action = APT::String::Strip(list[1]); + + // this is what we support in the processing stage + if(action != "install" && action != "configure" && + action != "remove" && action != "purge" && action != "purge") + { + if (Debug == true) + std::clog << "ignoring processing action: '" << action + << "'" << std::endl; + return; + } + } + // "status" has the form: "status: pkg: state" + // with state in ["half-installed", "unpacked", "half-configured", + // "installed", "config-files", "not-installed"] + else if (prefix == "status") { + pkgname = APT::String::Strip(list[1]); + action = APT::String::Strip(list[2]); + } else { if (Debug == true) - std::clog << "ignoring line: unknown prefix '" << list[0] << "'" - << std::endl; + std::clog << "unknown prefix '" << prefix << "'" << std::endl; return; } - std::string prefix = list[0]; - std::string pkgname; - std::string action; - if (prefix == "processing") + + /* handle the special cases first: + + errors look like this: + 'status: /var/cache/apt/archives/krecipes_0.8.1-0ubuntu1_i386.deb : error : trying to overwrite `/usr/share/doc/kde/HTML/en/krecipes/krectip.png', which is also in package krecipes-data + and conffile-prompt like this + 'status: conffile-prompt: conffile : 'current-conffile' 'new-conffile' useredited distedited + */ + if (prefix == "status") { - action = list[1]; - pkgname = list[2]; - if (action != "install" && action != "configure" && - action != "remove" && action != "purge" && - action != "disappear") + if(action == "error") + { + d->progress->Error(list[1], PackagesDone, PackagesTotal, + list[3]); + pkgFailures++; + WriteApportReport(list[1].c_str(), list[3].c_str()); + return; + } + else if(action == "conffile") + { + d->progress->ConffilePrompt(list[1], PackagesDone, PackagesTotal, + list[3]); return; - } else if (prefix == "status") { - pkgname = list[1]; - action = list[2]; + } } - // dpkg does not always send out the architecture so we need to guess - // it here - pkgname = ExpandShortPackageName(Cache, pkgname); + // at this point we know that we should have a valid pkgname, so build all + // the info from it + + // dpkg does not send always send "pkgname:arch" so we add it here + // if needed + if (pkgname.find(":") == std::string::npos) + { + // find the package in the group that is in a touched by dpkg + // if there are multiple dpkg will send us a full pkgname:arch + pkgCache::GrpIterator Grp = Cache.FindGrp(pkgname); + if (Grp.end() == false) + { + pkgCache::PkgIterator P = Grp.PackageList(); + for (; P.end() != true; P = Grp.NextPkg(P)) + { + if(Cache[P].Mode != pkgDepCache::ModeKeep) + { + pkgname = P.FullName(); + break; + } + } + } + } + const char* const pkg = pkgname.c_str(); std::string short_pkgname = StringSplit(pkgname, ":")[0]; - std::string i18n_pkgname = short_pkgname; + std::string arch = ""; if (pkgname.find(":") != string::npos) - { - strprintf(i18n_pkgname, "%s (%s)", short_pkgname.c_str(), - StringSplit(pkgname, ":")[1].c_str()); - } + arch = StringSplit(pkgname, ":")[1]; + std::string i18n_pkgname = pkgname; + if (arch.size() != 0) + strprintf(i18n_pkgname, "%s (%s)", short_pkgname.c_str(), arch.c_str()); // 'processing' from dpkg looks like // 'processing: action: pkg' - if(strncmp(list[0].c_str(), "processing", strlen("processing")) == 0) + if(prefix == "processing") { const std::pair * const iter = std::find_if(PackageProcessingOpsBegin, @@ -628,62 +647,41 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line) std::clog << "ignoring unknown action: " << action << std::endl; return; } - - std::string pkg_action; - strprintf(pkg_action, _(iter->second), short_pkgname.c_str()); - - d->progress->StatusChanged(pkgname, PackagesDone, PackagesTotal, - pkg_action); - - if (strncmp(action.c_str(), "disappear", strlen("disappear")) == 0) + std::string msg; + strprintf(msg, _(iter->second), i18n_pkgname.c_str()); + d->progress->StatusChanged(pkgname, PackagesDone, PackagesTotal, msg); + + // FIXME: this needs a muliarch testcase + // FIXME2: is "pkgname" here reliable with dpkg only sending us + // short pkgnames? + if (action == "disappear") handleDisappearAction(pkgname); return; - } - - // FIXME: fix indent once this goes into debian/sid - if(strncmp(prefix.c_str(), "status", strlen("processing")) == 0) - { - - if(strncmp(action.c_str(),"error",strlen("error")) == 0) - { - d->progress->Error(list[1], PackagesDone, PackagesTotal, list[3]); - pkgFailures++; - WriteApportReport(list[1].c_str(), list[3].c_str()); - return; - } - else if(strncmp(action.c_str(),"conffile",strlen("conffile")) == 0) - { - d->progress->ConffilePrompt(list[1], PackagesDone, PackagesTotal, - list[3]); - return; - } else { + } - vector const &states = PackageOps[pkg]; - const char *next_action = NULL; - if(PackageOpsDone[pkg] < states.size()) - next_action = states[PackageOpsDone[pkg]].state; - // check if the package moved to the next dpkg state - if(next_action && (strcmp(action.c_str(), next_action) == 0)) + if (prefix == "status") { - // only read the translation if there is actually a next - // action - std::string translation; - strprintf(translation, _(states[PackageOpsDone[pkg]].str), - i18n_pkgname.c_str()); - - // we moved from one dpkg state to a new one, report that - PackageOpsDone[pkg]++; - PackagesDone++; - - // and send to the progress - d->progress->StatusChanged(pkgname, PackagesDone, PackagesTotal, - translation); - } - - if (Debug == true) - std::clog << "(parsed from dpkg) pkg: " << pkgname - << " action: " << action << endl; - } + vector const &states = PackageOps[pkg]; + const char *next_action = NULL; + if(PackageOpsDone[pkg] < states.size()) + next_action = states[PackageOpsDone[pkg]].state; + // check if the package moved to the next dpkg state + if(next_action && (action == next_action)) + { + // only read the translation if there is actually a next + // action + const char *translation = _(states[PackageOpsDone[pkg]].str); + std::string msg; + strprintf(msg, translation, i18n_pkgname.c_str()); + d->progress->StatusChanged(pkgname, PackagesDone, PackagesTotal, msg); + + // we moved from one dpkg state to a new one, report that + PackageOpsDone[pkg]++; + PackagesDone++; + } + if (Debug == true) + std::clog << "(parsed from dpkg) pkg: " << short_pkgname + << " action: " << action << endl; } } /*}}}*/ @@ -919,6 +917,8 @@ bool pkgDPkgPM::CloseLog() return true; } /*}}}*/ + /*}}}*/ +/*{{{*/ // This implements a racy version of pselect for those architectures // that don't have a working implementation. // FIXME: Probably can be removed on Lenny+1 @@ -938,18 +938,16 @@ static int racy_pselect(int nfds, fd_set *readfds, fd_set *writefds, sigprocmask(SIG_SETMASK, &origmask, 0); return retval; } -/*}}}*/ - - + /*}}}*/ // DPkgPM::Go - Run the sequence /*{{{*/ // --------------------------------------------------------------------- /* This globs the operations and calls dpkg - * + * * If it is called with a progress object apt will report the install * progress to this object. It maps the dpkg states a package goes * through to human readable (and i10n-able) * names and calculates a percentage for each step. -*/ + */ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) { pkgPackageManager::SigINTStop = false; @@ -1331,7 +1329,7 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) // this is the dpkg status-fd, we need to keep it _config->Set("APT::Keep-Fds::",fd[1]); - // Tell the progress that its starting and fork dpkg + // Tell the progress that its starting and fork dpkg // FIXME: this is called once per dpkg run which is *too often* d->progress->Start(); @@ -1372,7 +1370,6 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) if (fcntl(STDIN_FILENO,F_SETFL,Flags & (~(long)O_NONBLOCK)) < 0) _exit(100); } - /* No Job Control Stop Env is a magic dpkg var that prevents it from using sigstop */ putenv((char *)"DPKG_NO_TSTP=yes"); @@ -1441,6 +1438,7 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) if (select_ret < 0 && (errno == EINVAL || errno == ENOSYS)) select_ret = racy_pselect(max(master, _dpkgin)+1, &rfds, NULL, NULL, &tv, &original_sigmask); + d->progress->Pulse(); if (select_ret == 0) @@ -1509,7 +1507,6 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) d->progress->StatusChanged("", PackagesDone, PackagesTotal, ""); d->progress->Stop(); - if (pkgPackageManager::SigINTStop) _error->Warning(_("Operation was interrupted before it could finish")); -- cgit v1.2.3 From 65dbd5a1a32f63dae81c8b5814cd246f1154c38d Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 18 Oct 2013 18:26:56 +0200 Subject: re-add missing APT::String::Strip --- apt-pkg/contrib/strutl.cc | 17 ++++++++++++++++- apt-pkg/contrib/strutl.h | 7 +++++++ apt-pkg/deb/dpkgpm.cc | 7 ++++--- apt-pkg/iprogress.cc | 8 ++++++++ apt-pkg/iprogress.h | 2 +- 5 files changed, 36 insertions(+), 5 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 77e48962c..9f794927d 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -36,7 +36,22 @@ using namespace std; /*}}}*/ - +// Strip - Remove white space from the front and back of a string /*{{{*/ +// --------------------------------------------------------------------- +namespace APT { + namespace String { +std::string Strip(const std::string &s) +{ + size_t start = s.find_first_not_of(" \t\n"); + // only whitespace + if (start == string::npos) + return ""; + size_t end = s.find_last_not_of(" \t\n"); + return s.substr(start, end-start+1); +} +} +} + /*}}}*/ // UTF8ToCodeset - Convert some UTF-8 string for some codeset /*{{{*/ // --------------------------------------------------------------------- /* This is handy to use before display some information for enduser */ diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index b42e06491..c8fc317c0 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -33,6 +33,13 @@ using std::vector; using std::ostream; #endif +namespace APT { + namespace String { + std::string Strip(const std::string &s); + }; +}; + + bool UTF8ToCodeset(const char *codeset, const std::string &orig, std::string *dest); char *_strstrip(char *String); char *_strrstrip(char *String); // right strip only diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index b5f858022..5f1849b53 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -668,6 +668,10 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line) // check if the package moved to the next dpkg state if(next_action && (action == next_action)) { + // we moved from one dpkg state to a new one, report that + PackageOpsDone[pkg]++; + PackagesDone++; + // only read the translation if there is actually a next // action const char *translation = _(states[PackageOpsDone[pkg]].str); @@ -675,9 +679,6 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line) strprintf(msg, translation, i18n_pkgname.c_str()); d->progress->StatusChanged(pkgname, PackagesDone, PackagesTotal, msg); - // we moved from one dpkg state to a new one, report that - PackageOpsDone[pkg]++; - PackagesDone++; } if (Debug == true) std::clog << "(parsed from dpkg) pkg: " << short_pkgname diff --git a/apt-pkg/iprogress.cc b/apt-pkg/iprogress.cc index 318d626d4..daa7695e2 100644 --- a/apt-pkg/iprogress.cc +++ b/apt-pkg/iprogress.cc @@ -29,6 +29,7 @@ bool PackageManager::StatusChanged(std::string PackageName, } PackageManagerProgressFd::PackageManagerProgressFd(int progress_fd) + : StepsDone(0), StepsTotal(1) { OutStatusFd = progress_fd; } @@ -106,6 +107,13 @@ bool PackageManagerProgressFd::StatusChanged(std::string PackageName, << ":" << pkg_action << std::endl; WriteToStatusFd(status.str()); + + if(_config->FindB("Debug::APT::Progress::PackageManagerFd", false) == true) + std::cerr << "progress: " << PackageName << " " << xStepsDone + << " " << xTotalSteps << " " << pkg_action + << std::endl; + + return true; } diff --git a/apt-pkg/iprogress.h b/apt-pkg/iprogress.h index ccf154279..42fa89be4 100644 --- a/apt-pkg/iprogress.h +++ b/apt-pkg/iprogress.h @@ -21,7 +21,7 @@ namespace Progress { public: PackageManager() - : percentage(0.0), last_reported_progress(0) {}; + : percentage(0.0), last_reported_progress(-1) {}; virtual ~PackageManager() {}; virtual void Start() {}; -- cgit v1.2.3 From 1c6cedc489b5eaeed1b7fdb845eca06bc1fccd4f Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 21 Oct 2013 21:23:07 +0200 Subject: move iprogress.{cc,h} to private-progress.{cc,h} until its fully stable --- apt-pkg/iprogress.cc | 221 --------------------------------------------------- apt-pkg/iprogress.h | 109 ------------------------- apt-pkg/makefile | 4 +- 3 files changed, 2 insertions(+), 332 deletions(-) delete mode 100644 apt-pkg/iprogress.cc delete mode 100644 apt-pkg/iprogress.h (limited to 'apt-pkg') diff --git a/apt-pkg/iprogress.cc b/apt-pkg/iprogress.cc deleted file mode 100644 index daa7695e2..000000000 --- a/apt-pkg/iprogress.cc +++ /dev/null @@ -1,221 +0,0 @@ -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -namespace APT { -namespace Progress { - -bool PackageManager::StatusChanged(std::string PackageName, - unsigned int StepsDone, - unsigned int TotalSteps, - std::string HumanReadableAction) -{ - int reporting_steps = _config->FindI("DpkgPM::Reporting-Steps", 1); - percentage = StepsDone/(float)TotalSteps * 100.0; - strprintf(progress_str, _("Progress: [%3i%%]"), (int)percentage); - - if(percentage < (last_reported_progress + reporting_steps)) - return false; - - return true; -} - -PackageManagerProgressFd::PackageManagerProgressFd(int progress_fd) - : StepsDone(0), StepsTotal(1) -{ - OutStatusFd = progress_fd; -} - -void PackageManagerProgressFd::WriteToStatusFd(std::string s) -{ - if(OutStatusFd <= 0) - return; - FileFd::Write(OutStatusFd, s.c_str(), s.size()); -} - -void PackageManagerProgressFd::Start() -{ - if(OutStatusFd <= 0) - return; - - // FIXME: use SetCloseExec here once it taught about throwing - // exceptions instead of doing _exit(100) on failure - fcntl(OutStatusFd,F_SETFD,FD_CLOEXEC); - - // send status information that we are about to fork dpkg - std::ostringstream status; - status << "pmstatus:dpkg-exec:" - << (StepsDone/float(StepsTotal)*100.0) - << ":" << _("Running dpkg") - << std::endl; - WriteToStatusFd(status.str()); -} - -void PackageManagerProgressFd::Stop() -{ - // clear the Keep-Fd again - _config->Clear("APT::Keep-Fds", OutStatusFd); -} - -void PackageManagerProgressFd::Error(std::string PackageName, - unsigned int StepsDone, - unsigned int TotalSteps, - std::string ErrorMessage) -{ - std::ostringstream status; - status << "pmerror:" << PackageName - << ":" << (StepsDone/float(TotalSteps)*100.0) - << ":" << ErrorMessage - << std::endl; - WriteToStatusFd(status.str()); -} - -void PackageManagerProgressFd::ConffilePrompt(std::string PackageName, - unsigned int StepsDone, - unsigned int TotalSteps, - std::string ConfMessage) -{ - std::ostringstream status; - status << "pmconffile:" << PackageName - << ":" << (StepsDone/float(TotalSteps)*100.0) - << ":" << ConfMessage - << std::endl; - WriteToStatusFd(status.str()); -} - - -bool PackageManagerProgressFd::StatusChanged(std::string PackageName, - unsigned int xStepsDone, - unsigned int xTotalSteps, - std::string pkg_action) -{ - StepsDone = xStepsDone; - StepsTotal = xTotalSteps; - - // build the status str - std::ostringstream status; - status << "pmstatus:" << StringSplit(PackageName, ":")[0] - << ":" << (StepsDone/float(StepsTotal)*100.0) - << ":" << pkg_action - << std::endl; - WriteToStatusFd(status.str()); - - if(_config->FindB("Debug::APT::Progress::PackageManagerFd", false) == true) - std::cerr << "progress: " << PackageName << " " << xStepsDone - << " " << xTotalSteps << " " << pkg_action - << std::endl; - - - return true; -} - -void PackageManagerFancy::SetupTerminalScrollArea(int nr_rows) -{ - // scroll down a bit to avoid visual glitch when the screen - // area shrinks by one row - std::cout << "\n"; - - // save cursor - std::cout << "\033[s"; - - // set scroll region (this will place the cursor in the top left) - std::cout << "\033[1;" << nr_rows - 1 << "r"; - - // restore cursor but ensure its inside the scrolling area - std::cout << "\033[u"; - static const char *move_cursor_up = "\033[1A"; - std::cout << move_cursor_up; - - std::flush(std::cout); -} - -PackageManagerFancy::PackageManagerFancy() - : nr_terminal_rows(-1) -{ - struct winsize win; - if(ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&win) == 0) - { - nr_terminal_rows = win.ws_row; - } -} - -void PackageManagerFancy::Start() -{ - if (nr_terminal_rows > 0) - SetupTerminalScrollArea(nr_terminal_rows); -} - -void PackageManagerFancy::Stop() -{ - if (nr_terminal_rows > 0) - { - SetupTerminalScrollArea(nr_terminal_rows + 1); - - // override the progress line (sledgehammer) - static const char* clear_screen_below_cursor = "\033[J"; - std::cout << clear_screen_below_cursor; - } -} - -bool PackageManagerFancy::StatusChanged(std::string PackageName, - unsigned int StepsDone, - unsigned int TotalSteps, - std::string HumanReadableAction) -{ - if (!PackageManager::StatusChanged(PackageName, StepsDone, TotalSteps, - HumanReadableAction)) - return false; - - int row = nr_terminal_rows; - - static string save_cursor = "\033[s"; - static string restore_cursor = "\033[u"; - - static string set_bg_color = "\033[42m"; // green - static string set_fg_color = "\033[30m"; // black - - static string restore_bg = "\033[49m"; - static string restore_fg = "\033[39m"; - - std::cout << save_cursor - // move cursor position to last row - << "\033[" << row << ";0f" - << set_bg_color - << set_fg_color - << progress_str - << restore_cursor - << restore_bg - << restore_fg; - std::flush(std::cout); - last_reported_progress = percentage; - - return true; -} - -bool PackageManagerText::StatusChanged(std::string PackageName, - unsigned int StepsDone, - unsigned int TotalSteps, - std::string HumanReadableAction) -{ - if (!PackageManager::StatusChanged(PackageName, StepsDone, TotalSteps, HumanReadableAction)) - return false; - - std::cout << progress_str << "\r\n"; - std::flush(std::cout); - - last_reported_progress = percentage; - - return true; -} - - -}; // namespace progress -}; // namespace apt diff --git a/apt-pkg/iprogress.h b/apt-pkg/iprogress.h deleted file mode 100644 index 42fa89be4..000000000 --- a/apt-pkg/iprogress.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef PKGLIB_IPROGRESS_H -#define PKGLIB_IPROGRESS_H - -#include -#include - - -namespace APT { -namespace Progress { - - class PackageManager - { - private: - /** \brief dpointer placeholder */ - void *d; - - protected: - std::string progress_str; - float percentage; - int last_reported_progress; - - public: - PackageManager() - : percentage(0.0), last_reported_progress(-1) {}; - virtual ~PackageManager() {}; - - virtual void Start() {}; - virtual void Stop() {}; - - virtual pid_t fork() {return fork(); }; - - virtual void Pulse() {}; - virtual long GetPulseInterval() { - return 500000; - }; - - virtual bool StatusChanged(std::string PackageName, - unsigned int StepsDone, - unsigned int TotalSteps, - std::string HumanReadableAction) ; - virtual void Error(std::string PackageName, - unsigned int StepsDone, - unsigned int TotalSteps, - std::string ErrorMessage) {}; - virtual void ConffilePrompt(std::string PackageName, - unsigned int StepsDone, - unsigned int TotalSteps, - std::string ConfMessage) {}; - }; - - class PackageManagerProgressFd : public PackageManager - { - protected: - int OutStatusFd; - int StepsDone; - int StepsTotal; - void WriteToStatusFd(std::string msg); - - public: - PackageManagerProgressFd(int progress_fd); - - virtual void Start(); - virtual void Stop(); - - virtual bool StatusChanged(std::string PackageName, - unsigned int StepsDone, - unsigned int TotalSteps, - std::string HumanReadableAction); - virtual void Error(std::string PackageName, - unsigned int StepsDone, - unsigned int TotalSteps, - std::string ErrorMessage); - virtual void ConffilePrompt(std::string PackageName, - unsigned int StepsDone, - unsigned int TotalSteps, - std::string ConfMessage); - - }; - - class PackageManagerFancy : public PackageManager - { - protected: - int nr_terminal_rows; - void SetupTerminalScrollArea(int nr_rows); - - public: - PackageManagerFancy(); - virtual void Start(); - virtual void Stop(); - virtual bool StatusChanged(std::string PackageName, - unsigned int StepsDone, - unsigned int TotalSteps, - std::string HumanReadableAction); - }; - - class PackageManagerText : public PackageManager - { - public: - virtual bool StatusChanged(std::string PackageName, - unsigned int StepsDone, - unsigned int TotalSteps, - std::string HumanReadableAction); - }; - - -}; // namespace Progress -}; // namespace APT - -#endif diff --git a/apt-pkg/makefile b/apt-pkg/makefile index e69b5ce7f..abf701511 100644 --- a/apt-pkg/makefile +++ b/apt-pkg/makefile @@ -43,7 +43,7 @@ SOURCE+= pkgcache.cc version.cc depcache.cc \ srcrecords.cc cachefile.cc versionmatch.cc policy.cc \ pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc \ indexrecords.cc vendor.cc vendorlist.cc cdrom.cc indexcopy.cc \ - aptconfiguration.cc cachefilter.cc cacheset.cc edsp.cc iprogress.cc + aptconfiguration.cc cachefilter.cc cacheset.cc edsp.cc HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \ orderlist.h sourcelist.h packagemanager.h tagfile.h \ init.h pkgcache.h version.h progress.h pkgrecords.h \ @@ -51,7 +51,7 @@ HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \ clean.h srcrecords.h cachefile.h versionmatch.h policy.h \ pkgsystem.h indexfile.h metaindex.h indexrecords.h vendor.h \ vendorlist.h cdrom.h indexcopy.h aptconfiguration.h \ - cachefilter.h cacheset.h edsp.h iprogress.h + cachefilter.h cacheset.h edsp.h # Source code for the debian specific components # In theory the deb headers do not need to be exported.. -- cgit v1.2.3 From d274520ee8d174aa9f062f2fbb2c4d117a121dd8 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 21 Oct 2013 21:24:32 +0200 Subject: fix apt output ordering and update test to match the new human friendly messages that include the architecture --- apt-pkg/deb/dpkgpm.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 5f1849b53..a61f08d91 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -668,14 +668,15 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line) // check if the package moved to the next dpkg state if(next_action && (action == next_action)) { - // we moved from one dpkg state to a new one, report that - PackageOpsDone[pkg]++; - PackagesDone++; - // only read the translation if there is actually a next // action const char *translation = _(states[PackageOpsDone[pkg]].str); std::string msg; + + // we moved from one dpkg state to a new one, report that + PackageOpsDone[pkg]++; + PackagesDone++; + strprintf(msg, translation, i18n_pkgname.c_str()); d->progress->StatusChanged(pkgname, PackagesDone, PackagesTotal, msg); @@ -1505,7 +1506,6 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) CloseLog(); // dpkg is done at this point - d->progress->StatusChanged("", PackagesDone, PackagesTotal, ""); d->progress->Stop(); if (pkgPackageManager::SigINTStop) -- cgit v1.2.3 From 3b1b0f2900347ef2836c7ee4cc3ee20c6cdcb621 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 21 Oct 2013 21:42:16 +0200 Subject: restore binary compatiblity with the pkgPackageManager interface --- apt-pkg/deb/dpkgpm.cc | 3 ++- apt-pkg/packagemanager.cc | 25 +++++++++++++++++++++++++ apt-pkg/packagemanager.h | 18 ++++++++---------- 3 files changed, 35 insertions(+), 11 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index a61f08d91..adc94f05c 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -19,7 +19,8 @@ #include #include #include -#include + +#include #include #include diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index 3690a64c3..a2079a2e4 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -1027,6 +1027,18 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() return Completed; } +// PM::DoInstallPostFork - compat /*{{{*/ +// --------------------------------------------------------------------- + /*}}}*/ +pkgPackageManager::OrderResult +pkgPackageManager::DoInstallPostFork(int statusFd) +{ + APT::Progress::PackageManager *progress = new + APT::Progress::PackageManagerProgressFd(statusFd); + pkgPackageManager::OrderResult res = DoInstallPostFork(progress); + delete progress; + return res; + } /*}}}*/ // PM::DoInstallPostFork - Does install part that happens after the fork /*{{{*/ // --------------------------------------------------------------------- @@ -1042,6 +1054,19 @@ pkgPackageManager::DoInstallPostFork(APT::Progress::PackageManager *progress) /*}}}*/ // PM::DoInstall - Does the installation /*{{{*/ // --------------------------------------------------------------------- +/* compat */ +pkgPackageManager::OrderResult +pkgPackageManager::DoInstall(int statusFd) +{ + APT::Progress::PackageManager *progress = new + APT::Progress::PackageManagerProgressFd(statusFd); + OrderResult res = DoInstall(progress); + delete progress; + return res; + } + /*}}}*/ +// PM::DoInstall - Does the installation /*{{{*/ +// --------------------------------------------------------------------- /* This uses the filenames in FileNames and the information in the DepCache to perform the installation of packages.*/ pkgPackageManager::OrderResult diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index 5c15ac0e4..dcd12f979 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -23,8 +23,10 @@ #ifndef PKGLIB_PACKAGEMANAGER_H #define PKGLIB_PACKAGEMANAGER_H +#include #include -#include + +#include #include #include @@ -100,16 +102,8 @@ class pkgPackageManager : protected pkgCache::Namespace // Do the installation OrderResult DoInstall(APT::Progress::PackageManager *progress); - // compat - OrderResult DoInstall(int statusFd=-1) { - APT::Progress::PackageManager *progress = new - APT::Progress::PackageManagerProgressFd(statusFd); - OrderResult res = DoInstall(progress); - delete progress; - return res; - } - + __deprecated OrderResult DoInstall(int statusFd=-1); // stuff that needs to be done before the fork() of a library that // uses apt @@ -120,6 +114,10 @@ class pkgPackageManager : protected pkgCache::Namespace // stuff that needs to be done after the fork OrderResult DoInstallPostFork(APT::Progress::PackageManager *progress); + // compat + __deprecated OrderResult DoInstallPostFork(int statusFd=-1); + + // ? bool FixMissing(); /** \brief returns all packages dpkg let disappear */ -- cgit v1.2.3 From 8336ae355b8a22877cd233063c715688155aa617 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 22 Oct 2013 18:44:14 +0200 Subject: move install-progress.{cc,h} to apt-pkg --- apt-pkg/install-progress.cc | 306 ++++++++++++++++++++++++++++++++++++++++++++ apt-pkg/install-progress.h | 137 ++++++++++++++++++++ apt-pkg/makefile | 5 +- 3 files changed, 446 insertions(+), 2 deletions(-) create mode 100644 apt-pkg/install-progress.cc create mode 100644 apt-pkg/install-progress.h (limited to 'apt-pkg') diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc new file mode 100644 index 000000000..1d15228c2 --- /dev/null +++ b/apt-pkg/install-progress.cc @@ -0,0 +1,306 @@ +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +namespace APT { +namespace Progress { + +bool PackageManager::StatusChanged(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string HumanReadableAction) +{ + int reporting_steps = _config->FindI("DpkgPM::Reporting-Steps", 1); + percentage = StepsDone/(float)TotalSteps * 100.0; + strprintf(progress_str, _("Progress: [%3i%%]"), (int)percentage); + + if(percentage < (last_reported_progress + reporting_steps)) + return false; + + return true; +} + +PackageManagerProgressFd::PackageManagerProgressFd(int progress_fd) + : StepsDone(0), StepsTotal(1) +{ + OutStatusFd = progress_fd; +} + +void PackageManagerProgressFd::WriteToStatusFd(std::string s) +{ + if(OutStatusFd <= 0) + return; + FileFd::Write(OutStatusFd, s.c_str(), s.size()); +} + +void PackageManagerProgressFd::Start() +{ + if(OutStatusFd <= 0) + return; + + // FIXME: use SetCloseExec here once it taught about throwing + // exceptions instead of doing _exit(100) on failure + fcntl(OutStatusFd,F_SETFD,FD_CLOEXEC); + + // send status information that we are about to fork dpkg + std::ostringstream status; + status << "pmstatus:dpkg-exec:" + << (StepsDone/float(StepsTotal)*100.0) + << ":" << _("Running dpkg") + << std::endl; + WriteToStatusFd(status.str()); +} + +void PackageManagerProgressFd::Stop() +{ + // clear the Keep-Fd again + _config->Clear("APT::Keep-Fds", OutStatusFd); +} + +void PackageManagerProgressFd::Error(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ErrorMessage) +{ + std::ostringstream status; + status << "pmerror:" << PackageName + << ":" << (StepsDone/float(TotalSteps)*100.0) + << ":" << ErrorMessage + << std::endl; + WriteToStatusFd(status.str()); +} + +void PackageManagerProgressFd::ConffilePrompt(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ConfMessage) +{ + std::ostringstream status; + status << "pmconffile:" << PackageName + << ":" << (StepsDone/float(TotalSteps)*100.0) + << ":" << ConfMessage + << std::endl; + WriteToStatusFd(status.str()); +} + + +bool PackageManagerProgressFd::StatusChanged(std::string PackageName, + unsigned int xStepsDone, + unsigned int xTotalSteps, + std::string pkg_action) +{ + StepsDone = xStepsDone; + StepsTotal = xTotalSteps; + + // build the status str + std::ostringstream status; + status << "pmstatus:" << StringSplit(PackageName, ":")[0] + << ":" << (StepsDone/float(StepsTotal)*100.0) + << ":" << pkg_action + << std::endl; + WriteToStatusFd(status.str()); + + if(_config->FindB("Debug::APT::Progress::PackageManagerFd", false) == true) + std::cerr << "progress: " << PackageName << " " << xStepsDone + << " " << xTotalSteps << " " << pkg_action + << std::endl; + + + return true; +} + + +PackageManagerProgressDeb822Fd::PackageManagerProgressDeb822Fd(int progress_fd) + : StepsDone(0), StepsTotal(1) +{ + OutStatusFd = progress_fd; +} + +void PackageManagerProgressDeb822Fd::WriteToStatusFd(std::string s) +{ + FileFd::Write(OutStatusFd, s.c_str(), s.size()); +} + +void PackageManagerProgressDeb822Fd::Start() +{ + // FIXME: use SetCloseExec here once it taught about throwing + // exceptions instead of doing _exit(100) on failure + fcntl(OutStatusFd,F_SETFD,FD_CLOEXEC); + + // send status information that we are about to fork dpkg + std::ostringstream status; + status << "Status: " << "progress" << std::endl + << "Percent: " << (StepsDone/float(StepsTotal)*100.0) << std::endl + << "Message: " << _("Running dpkg") << std::endl + << std::endl; + WriteToStatusFd(status.str()); +} + +void PackageManagerProgressDeb822Fd::Stop() +{ + // clear the Keep-Fd again + _config->Clear("APT::Keep-Fds", OutStatusFd); +} + +void PackageManagerProgressDeb822Fd::Error(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ErrorMessage) +{ + std::ostringstream status; + status << "Status: " << "Error" << std::endl + << "Package:" << PackageName << std::endl + << "Percent: " << (StepsDone/float(TotalSteps)*100.0) << std::endl + << "Message: " << ErrorMessage << std::endl + << std::endl; + WriteToStatusFd(status.str()); +} + +void PackageManagerProgressDeb822Fd::ConffilePrompt(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ConfMessage) +{ + std::ostringstream status; + status << "Status: " << "ConfFile" << std::endl + << "Package:" << PackageName << std::endl + << "Percent: " << (StepsDone/float(TotalSteps)*100.0) << std::endl + << "Message: " << ConfMessage << std::endl + << std::endl; + WriteToStatusFd(status.str()); +} + + +bool PackageManagerProgressDeb822Fd::StatusChanged(std::string PackageName, + unsigned int xStepsDone, + unsigned int xTotalSteps, + std::string message) +{ + StepsDone = xStepsDone; + StepsTotal = xTotalSteps; + + // build the status str + std::ostringstream status; + status << "Status: " << "progress" << std::endl + << "Package: " << PackageName << std::endl + << "Percent: " << (StepsDone/float(StepsTotal)*100.0) << std::endl + << "Message: " << message << std::endl + << std::endl; + WriteToStatusFd(status.str()); + + return true; +} + + +void PackageManagerFancy::SetupTerminalScrollArea(int nr_rows) +{ + // scroll down a bit to avoid visual glitch when the screen + // area shrinks by one row + std::cout << "\n"; + + // save cursor + std::cout << "\033[s"; + + // set scroll region (this will place the cursor in the top left) + std::cout << "\033[1;" << nr_rows - 1 << "r"; + + // restore cursor but ensure its inside the scrolling area + std::cout << "\033[u"; + static const char *move_cursor_up = "\033[1A"; + std::cout << move_cursor_up; + + std::flush(std::cout); +} + +PackageManagerFancy::PackageManagerFancy() + : nr_terminal_rows(-1) +{ + struct winsize win; + if(ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&win) == 0) + { + nr_terminal_rows = win.ws_row; + } +} + +void PackageManagerFancy::Start() +{ + if (nr_terminal_rows > 0) + SetupTerminalScrollArea(nr_terminal_rows); +} + +void PackageManagerFancy::Stop() +{ + if (nr_terminal_rows > 0) + { + SetupTerminalScrollArea(nr_terminal_rows + 1); + + // override the progress line (sledgehammer) + static const char* clear_screen_below_cursor = "\033[J"; + std::cout << clear_screen_below_cursor; + } +} + +bool PackageManagerFancy::StatusChanged(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string HumanReadableAction) +{ + if (!PackageManager::StatusChanged(PackageName, StepsDone, TotalSteps, + HumanReadableAction)) + return false; + + int row = nr_terminal_rows; + + static string save_cursor = "\033[s"; + static string restore_cursor = "\033[u"; + + static string set_bg_color = "\033[42m"; // green + static string set_fg_color = "\033[30m"; // black + + static string restore_bg = "\033[49m"; + static string restore_fg = "\033[39m"; + + std::cout << save_cursor + // move cursor position to last row + << "\033[" << row << ";0f" + << set_bg_color + << set_fg_color + << progress_str + << restore_cursor + << restore_bg + << restore_fg; + std::flush(std::cout); + last_reported_progress = percentage; + + return true; +} + +bool PackageManagerText::StatusChanged(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string HumanReadableAction) +{ + if (!PackageManager::StatusChanged(PackageName, StepsDone, TotalSteps, HumanReadableAction)) + return false; + + std::cout << progress_str << "\r\n"; + std::flush(std::cout); + + last_reported_progress = percentage; + + return true; +} + + + +}; // namespace progress +}; // namespace apt diff --git a/apt-pkg/install-progress.h b/apt-pkg/install-progress.h new file mode 100644 index 000000000..9c31eac92 --- /dev/null +++ b/apt-pkg/install-progress.h @@ -0,0 +1,137 @@ +#ifndef PKGLIB_IPROGRESS_H +#define PKGLIB_IPROGRESS_H + +#include +#include + + +namespace APT { +namespace Progress { + + class PackageManager + { + private: + /** \brief dpointer placeholder */ + void *d; + + protected: + std::string progress_str; + float percentage; + int last_reported_progress; + + public: + PackageManager() + : percentage(0.0), last_reported_progress(-1) {}; + virtual ~PackageManager() {}; + + virtual void Start() {}; + virtual void Stop() {}; + + virtual pid_t fork() {return fork(); }; + + virtual void Pulse() {}; + virtual long GetPulseInterval() { + return 500000; + }; + + virtual bool StatusChanged(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string HumanReadableAction) ; + virtual void Error(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ErrorMessage) {}; + virtual void ConffilePrompt(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ConfMessage) {}; + }; + + class PackageManagerProgressFd : public PackageManager + { + protected: + int OutStatusFd; + int StepsDone; + int StepsTotal; + void WriteToStatusFd(std::string msg); + + public: + PackageManagerProgressFd(int progress_fd); + + virtual void Start(); + virtual void Stop(); + + virtual bool StatusChanged(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string HumanReadableAction); + virtual void Error(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ErrorMessage); + virtual void ConffilePrompt(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ConfMessage); + + }; + + class PackageManagerProgressDeb822Fd : public PackageManager + { + protected: + int OutStatusFd; + int StepsDone; + int StepsTotal; + void WriteToStatusFd(std::string msg); + + public: + PackageManagerProgressDeb822Fd(int progress_fd); + + virtual void Start(); + virtual void Stop(); + + virtual bool StatusChanged(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string HumanReadableAction); + virtual void Error(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ErrorMessage); + virtual void ConffilePrompt(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ConfMessage); + }; + + class PackageManagerFancy : public PackageManager + { + protected: + int nr_terminal_rows; + void SetupTerminalScrollArea(int nr_rows); + + public: + PackageManagerFancy(); + virtual void Start(); + virtual void Stop(); + virtual bool StatusChanged(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string HumanReadableAction); + }; + + class PackageManagerText : public PackageManager + { + public: + virtual bool StatusChanged(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string HumanReadableAction); + }; + + +}; // namespace Progress +}; // namespace APT + +#endif diff --git a/apt-pkg/makefile b/apt-pkg/makefile index abf701511..503bd7839 100644 --- a/apt-pkg/makefile +++ b/apt-pkg/makefile @@ -43,7 +43,8 @@ SOURCE+= pkgcache.cc version.cc depcache.cc \ srcrecords.cc cachefile.cc versionmatch.cc policy.cc \ pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc \ indexrecords.cc vendor.cc vendorlist.cc cdrom.cc indexcopy.cc \ - aptconfiguration.cc cachefilter.cc cacheset.cc edsp.cc + aptconfiguration.cc cachefilter.cc cacheset.cc edsp.cc \ + install-progress.cc HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \ orderlist.h sourcelist.h packagemanager.h tagfile.h \ init.h pkgcache.h version.h progress.h pkgrecords.h \ @@ -51,7 +52,7 @@ HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \ clean.h srcrecords.h cachefile.h versionmatch.h policy.h \ pkgsystem.h indexfile.h metaindex.h indexrecords.h vendor.h \ vendorlist.h cdrom.h indexcopy.h aptconfiguration.h \ - cachefilter.h cacheset.h edsp.h + cachefilter.h cacheset.h edsp.h install-progress.h # Source code for the debian specific components # In theory the deb headers do not need to be exported.. -- cgit v1.2.3 From af36becc889122909d677c267bc5325fb73b6151 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 22 Oct 2013 19:02:01 +0200 Subject: fix install-progress location --- apt-pkg/deb/dpkgpm.cc | 3 +-- apt-pkg/install-progress.cc | 3 +-- apt-pkg/packagemanager.h | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index adc94f05c..c98ff3e04 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -19,8 +19,7 @@ #include #include #include - -#include +#include #include #include diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc index 1d15228c2..9d0d4e3f1 100644 --- a/apt-pkg/install-progress.cc +++ b/apt-pkg/install-progress.cc @@ -1,8 +1,7 @@ #include #include #include - -#include +#include #include diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index dcd12f979..8ffac2f13 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -25,8 +25,7 @@ #include #include - -#include +#include #include #include -- cgit v1.2.3 From 1f467276115ddc43b766dbd1107eb2fb315dc747 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 22 Oct 2013 21:15:55 +0200 Subject: use Pkg.FullName() in disappearedPkgs and remove duplicated check --- apt-pkg/deb/dpkgpm.cc | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index c98ff3e04..889b62afa 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -550,16 +550,6 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line) { pkgname = APT::String::Strip(list[2]); action = APT::String::Strip(list[1]); - - // this is what we support in the processing stage - if(action != "install" && action != "configure" && - action != "remove" && action != "purge" && action != "purge") - { - if (Debug == true) - std::clog << "ignoring processing action: '" << action - << "'" << std::endl; - return; - } } // "status" has the form: "status: pkg: state" // with state in ["half-installed", "unpacked", "half-configured", @@ -696,6 +686,7 @@ void pkgDPkgPM::handleDisappearAction(string const &pkgname) pkgCache::PkgIterator Pkg = Cache.FindPkg(pkgname); if (unlikely(Pkg.end() == true)) return; + // the disappeared package was auto-installed - nothing to do if ((Cache[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) return; @@ -1218,7 +1209,7 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) { if((*I).Pkg.end() == true) continue; - if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.Name()) != disappearedPkgs.end()) + if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.FullName()) != 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 || -- cgit v1.2.3 From b4017ba767e15dc06c73915efaf36409ee099bf2 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 22 Oct 2013 21:53:49 +0200 Subject: fix failing ./test/integration/test-disappearing-packages (thanks Donkult!) --- apt-pkg/deb/dpkgpm.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 889b62afa..1a02115ba 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -680,13 +680,13 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line) // DPkgPM::handleDisappearAction /*{{{*/ void pkgDPkgPM::handleDisappearAction(string const &pkgname) { - // record the package name for display and stuff later - disappearedPkgs.insert(pkgname); - pkgCache::PkgIterator Pkg = Cache.FindPkg(pkgname); if (unlikely(Pkg.end() == true)) return; + // record the package name for display and stuff later + disappearedPkgs.insert(Pkg.FullName(true)); + // the disappeared package was auto-installed - nothing to do if ((Cache[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) return; @@ -1209,7 +1209,7 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) { if((*I).Pkg.end() == true) continue; - if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.FullName()) != disappearedPkgs.end()) + if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.FullName(true)) != 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 || -- cgit v1.2.3 From 4b9969da40ff1dff2f5787feff5103c873c57f7f Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 22 Oct 2013 21:55:02 +0200 Subject: fix failing ./test/integration/test-disappearing-packages (thanks Donkult) - ported from the mvo/feature/install-progress-refactor branch --- apt-pkg/deb/dpkgpm.cc | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 0ebd9f28b..ae895c9e6 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -555,16 +555,6 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) { pkgname = APT::String::Strip(list[2]); action = APT::String::Strip(list[1]); - - // this is what we support in the processing stage - if(action != "install" && action != "configure" && - action != "remove" && action != "purge" && action != "purge") - { - if (Debug == true) - std::clog << "ignoring processing action: '" << action - << "'" << std::endl; - return; - } } // "status" has the form: "status: pkg: state" // with state in ["half-installed", "unpacked", "half-configured", @@ -724,12 +714,13 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) // DPkgPM::handleDisappearAction /*{{{*/ void pkgDPkgPM::handleDisappearAction(string const &pkgname) { - // record the package name for display and stuff later - disappearedPkgs.insert(pkgname); - pkgCache::PkgIterator Pkg = Cache.FindPkg(pkgname); if (unlikely(Pkg.end() == true)) return; + + // record the package name for display and stuff later + disappearedPkgs.insert(Pkg.FullName(true)); + // the disappeared package was auto-installed - nothing to do if ((Cache[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) return; @@ -1332,7 +1323,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) { if((*I).Pkg.end() == true) continue; - if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.Name()) != disappearedPkgs.end()) + if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.FullName(true)) != 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 || -- cgit v1.2.3 From a18456a58a9ad2fe33f7fbd202533a115712df96 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 24 Oct 2013 08:31:50 +0200 Subject: make the main loop a while() instead of a for() as I find this (much) easier to read this way) --- apt-pkg/deb/dpkgpm.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 1a02115ba..56358ae87 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1087,8 +1087,9 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) dpkgMultiArch = true; } - // this loop is runs once per operation - for (vector::const_iterator I = List.begin(); I != List.end();) + // go over each item + vector::const_iterator I = List.begin(); + while (I != List.end()) { // Do all actions with the same Op in one run vector::const_iterator J = I; -- cgit v1.2.3 From 6fad3c240c18dff339d934f2e3bd41c93c417f89 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 25 Oct 2013 15:43:28 +0200 Subject: extract getDpkgExecutable() and DPkgPM::BuildPackagesProgressMap() out of the monster long pkgDPkgPM::Go() --- apt-pkg/deb/dpkgpm.cc | 136 +++++++++++++++++++++++++++----------------------- apt-pkg/deb/dpkgpm.h | 3 ++ 2 files changed, 77 insertions(+), 62 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 56358ae87..98fb7581a 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -132,6 +132,20 @@ ionice(int PID) return ExecWait(Process, "ionice"); } +static std::string getDpkgExecutable() +{ + string Tmp = _config->Find("Dir::Bin::dpkg","dpkg"); + string const dpkgChrootDir = _config->FindDir("DPkg::Chroot-Directory", "/"); + size_t dpkgChrootLen = dpkgChrootDir.length(); + if (dpkgChrootDir != "/" && Tmp.find(dpkgChrootDir) == 0) + { + if (dpkgChrootDir[dpkgChrootLen - 1] == '/') + --dpkgChrootLen; + Tmp = Tmp.substr(dpkgChrootLen); + } + return Tmp; +} + // dpkgChrootDirectory - chrooting for dpkg if needed /*{{{*/ static void dpkgChrootDirectory() { @@ -932,6 +946,60 @@ static int racy_pselect(int nfds, fd_set *readfds, fd_set *writefds, return retval; } /*}}}*/ + +// DPkgPM::BuildPackagesProgressMap /*{{{*/ +void pkgDPkgPM::BuildPackagesProgressMap() +{ + // map the dpkg states to the operations that are performed + // (this is sorted in the same way as Item::Ops) + static const struct DpkgState DpkgStatesOpMap[][7] = { + // Install operation + { + {"half-installed", N_("Preparing %s")}, + {"unpacked", N_("Unpacking %s") }, + {NULL, NULL} + }, + // Configure operation + { + {"unpacked",N_("Preparing to configure %s") }, + {"half-configured", N_("Configuring %s") }, + { "installed", N_("Installed %s")}, + {NULL, NULL} + }, + // Remove operation + { + {"half-configured", N_("Preparing for removal of %s")}, + {"half-installed", N_("Removing %s")}, + {"config-files", N_("Removed %s")}, + {NULL, NULL} + }, + // Purge operation + { + {"config-files", N_("Preparing to completely remove %s")}, + {"not-installed", N_("Completely removed %s")}, + {NULL, NULL} + }, + }; + + // init the PackageOps map, go over the list of packages that + // 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) + { + if((*I).Pkg.end() == true) + continue; + + string const name = (*I).Pkg.FullName(); + PackageOpsDone[name] = 0; + for(int i=0; (DpkgStatesOpMap[(*I).Op][i]).state != NULL; ++i) + { + PackageOps[name].push_back(DpkgStatesOpMap[(*I).Op][i]); + PackagesTotal++; + } + } +} + /*}}}*/ // DPkgPM::Go - Run the sequence /*{{{*/ // --------------------------------------------------------------------- /* This globs the operations and calls dpkg @@ -947,21 +1015,11 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) d->progress = progress; // Generate the base argument list for dpkg - std::vector Args; unsigned long StartSize = 0; - string Tmp = _config->Find("Dir::Bin::dpkg","dpkg"); - { - string const dpkgChrootDir = _config->FindDir("DPkg::Chroot-Directory", "/"); - size_t dpkgChrootLen = dpkgChrootDir.length(); - if (dpkgChrootDir != "/" && Tmp.find(dpkgChrootDir) == 0) - { - if (dpkgChrootDir[dpkgChrootLen - 1] == '/') - --dpkgChrootLen; - Tmp = Tmp.substr(dpkgChrootLen); - } - } - Args.push_back(Tmp.c_str()); - StartSize += Tmp.length(); + std::vector Args; + std::string DpkgExecutable = getDpkgExecutable(); + Args.push_back(DpkgExecutable.c_str()); + StartSize += DpkgExecutable.length(); // Stick in any custom dpkg options Configuration::Item const *Opts = _config->Tree("DPkg::Options"); @@ -1018,54 +1076,8 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) if (_config->FindB("DPkg::ConfigurePending", SmartConf) == true) List.push_back(Item(Item::ConfigurePending, PkgIterator())); - // map the dpkg states to the operations that are performed - // (this is sorted in the same way as Item::Ops) - static const struct DpkgState DpkgStatesOpMap[][7] = { - // Install operation - { - {"half-installed", N_("Preparing %s")}, - {"unpacked", N_("Unpacking %s") }, - {NULL, NULL} - }, - // Configure operation - { - {"unpacked",N_("Preparing to configure %s") }, - {"half-configured", N_("Configuring %s") }, - { "installed", N_("Installed %s")}, - {NULL, NULL} - }, - // Remove operation - { - {"half-configured", N_("Preparing for removal of %s")}, - {"half-installed", N_("Removing %s")}, - {"config-files", N_("Removed %s")}, - {NULL, NULL} - }, - // Purge operation - { - {"config-files", N_("Preparing to completely remove %s")}, - {"not-installed", N_("Completely removed %s")}, - {NULL, NULL} - }, - }; - - // init the PackageOps map, go over the list of packages that - // 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) - { - if((*I).Pkg.end() == true) - continue; - - string const name = (*I).Pkg.FullName(); - PackageOpsDone[name] = 0; - for(int i=0; (DpkgStatesOpMap[(*I).Op][i]).state != NULL; ++i) - { - PackageOps[name].push_back(DpkgStatesOpMap[(*I).Op][i]); - PackagesTotal++; - } - } + // for the progress + BuildPackagesProgressMap(); d->stdin_is_dev_null = false; diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index 922631ba8..5f00eee5d 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -97,6 +97,9 @@ class pkgDPkgPM : public pkgPackageManager // dpkg log bool OpenLog(); bool CloseLog(); + + // helper + void BuildPackagesProgressMap(); // input processing void DoStdin(int master); -- cgit v1.2.3 From c3045b79796b611858e9f8b44127a70d6043cea0 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 31 Oct 2013 07:36:47 +0100 Subject: move pty stuff into its own function --- apt-pkg/deb/dpkgpm.cc | 173 +++++++++++++++++++++++++++----------------------- apt-pkg/deb/dpkgpm.h | 3 + 2 files changed, 97 insertions(+), 79 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 0ebd9f28b..ddfc7c04e 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -55,7 +55,7 @@ public: pkgDPkgPMPrivate() : stdin_is_dev_null(false), dpkgbuf_pos(0), term_out(NULL), history_out(NULL), last_reported_progress(0.0), nr_terminal_rows(0), - fancy_progress_output(false) + fancy_progress_output(false), master(-1), slave(-1) { dpkgbuf[0] = '\0'; if(_config->FindB("Dpkg::Progress-Fancy", false) == true) @@ -63,6 +63,7 @@ public: fancy_progress_output = true; _config->Set("DpkgPM::Progress", true); } + } bool stdin_is_dev_null; // the buffer we use for the dpkg status-fd reading @@ -75,6 +76,16 @@ public: float last_reported_progress; int nr_terminal_rows; bool fancy_progress_output; + + // pty stuff + struct termios tt; + int master; + int slave; + + // signals + sigset_t sigmask; + sigset_t original_sigmask; + }; namespace @@ -1055,6 +1066,61 @@ void pkgDPkgPM::CleanupTerminal() } } +void pkgDPkgPM::StartPtyMagic() +{ + // setup the pty and stuff + struct winsize win; + + // if tcgetattr does not return zero there was a error + // and we do not do any pty magic + _error->PushToStack(); + if (tcgetattr(STDOUT_FILENO, &d->tt) == 0) + { + ioctl(1, TIOCGWINSZ, (char *)&win); + d->nr_terminal_rows = win.ws_row; + if (openpty(&d->master, &d->slave, NULL, &d->tt, &win) < 0) + { + _error->Errno("openpty", _("Can not write log (%s)"), _("Is /dev/pts mounted?")); + d->master = d->slave = -1; + } else { + struct termios rtt; + rtt = d->tt; + cfmakeraw(&rtt); + rtt.c_lflag &= ~ECHO; + rtt.c_lflag |= ISIG; + // block SIGTTOU during tcsetattr to prevent a hang if + // the process is a member of the background process group + // http://www.opengroup.org/onlinepubs/000095399/functions/tcsetattr.html + sigemptyset(&d->sigmask); + sigaddset(&d->sigmask, SIGTTOU); + sigprocmask(SIG_BLOCK,&d->sigmask, &d->original_sigmask); + tcsetattr(0, TCSAFLUSH, &rtt); + sigprocmask(SIG_SETMASK, &d->original_sigmask, 0); + } + } + // complain only if stdout is either a terminal (but still failed) or is an invalid + // descriptor otherwise we would complain about redirection to e.g. /dev/null as well. + else if (isatty(STDOUT_FILENO) == 1 || errno == EBADF) + _error->Errno("tcgetattr", _("Can not write log (%s)"), _("Is stdout a terminal?")); + + if (_error->PendingError() == true) + _error->DumpErrors(std::cerr); + _error->RevertToStack(); + + // setup terminal + SetupTerminalScrollArea(d->nr_terminal_rows); +} + +void pkgDPkgPM::StopPtyMagic() +{ + if(d->slave > 0) + close(d->slave); + if(d->master >= 0) + { + tcsetattr(0, TCSAFLUSH, &d->tt); + close(d->master); + } +} // DPkgPM::Go - Run the sequence /*{{{*/ // --------------------------------------------------------------------- @@ -1121,8 +1187,6 @@ bool pkgDPkgPM::Go(int OutStatusFd) fd_set rfds; struct timespec tv; - sigset_t sigmask; - sigset_t original_sigmask; unsigned int const MaxArgs = _config->FindI("Dpkg::MaxArgs",8*1024); unsigned int const MaxArgBytes = _config->FindI("Dpkg::MaxArgBytes",32*1024); @@ -1210,8 +1274,12 @@ bool pkgDPkgPM::Go(int OutStatusFd) dpkgMultiArch = true; } - // this loop is runs once per operation - for (vector::const_iterator I = List.begin(); I != List.end();) + // start pty magic before the loop + StartPtyMagic(); + + // this loop is runs once per dpkg operation + vector::const_iterator I = List.begin(); + while (I != List.end()) { // Do all actions with the same Op in one run vector::const_iterator J = I; @@ -1402,47 +1470,6 @@ bool pkgDPkgPM::Go(int OutStatusFd) // ignore SIGHUP as well (debian #463030) sighandler_t old_SIGHUP = signal(SIGHUP,SIG_IGN); - struct termios tt; - struct winsize win; - int master = -1; - int slave = -1; - - // if tcgetattr does not return zero there was a error - // and we do not do any pty magic - _error->PushToStack(); - if (tcgetattr(STDOUT_FILENO, &tt) == 0) - { - ioctl(1, TIOCGWINSZ, (char *)&win); - d->nr_terminal_rows = win.ws_row; - if (openpty(&master, &slave, NULL, &tt, &win) < 0) - { - _error->Errno("openpty", _("Can not write log (%s)"), _("Is /dev/pts mounted?")); - master = slave = -1; - } else { - struct termios rtt; - rtt = tt; - cfmakeraw(&rtt); - rtt.c_lflag &= ~ECHO; - rtt.c_lflag |= ISIG; - // block SIGTTOU during tcsetattr to prevent a hang if - // the process is a member of the background process group - // http://www.opengroup.org/onlinepubs/000095399/functions/tcsetattr.html - sigemptyset(&sigmask); - sigaddset(&sigmask, SIGTTOU); - sigprocmask(SIG_BLOCK,&sigmask, &original_sigmask); - tcsetattr(0, TCSAFLUSH, &rtt); - sigprocmask(SIG_SETMASK, &original_sigmask, 0); - } - } - // complain only if stdout is either a terminal (but still failed) or is an invalid - // descriptor otherwise we would complain about redirection to e.g. /dev/null as well. - else if (isatty(STDOUT_FILENO) == 1 || errno == EBADF) - _error->Errno("tcgetattr", _("Can not write log (%s)"), _("Is stdout a terminal?")); - - if (_error->PendingError() == true) - _error->DumpErrors(std::cerr); - _error->RevertToStack(); - // Fork dpkg pid_t Child; _config->Set("APT::Keep-Fds::",fd[1]); @@ -1461,15 +1488,15 @@ bool pkgDPkgPM::Go(int OutStatusFd) if (Child == 0) { - if(slave >= 0 && master >= 0) + if(d->slave >= 0 && d->master >= 0) { setsid(); - ioctl(slave, TIOCSCTTY, 0); - close(master); - dup2(slave, 0); - dup2(slave, 1); - dup2(slave, 2); - close(slave); + ioctl(d->slave, TIOCSCTTY, 0); + close(d->master); + dup2(d->slave, 0); + dup2(d->slave, 1); + dup2(d->slave, 2); + close(d->slave); } close(fd[0]); // close the read end of the pipe @@ -1493,9 +1520,6 @@ bool pkgDPkgPM::Go(int OutStatusFd) if (fcntl(STDIN_FILENO,F_SETFL,Flags & (~(long)O_NONBLOCK)) < 0) _exit(100); } - // setup terminal - SetupTerminalScrollArea(d->nr_terminal_rows); - SendTerminalProgress(PackagesDone/float(PackagesTotal)*100.0); /* No Job Control Stop Env is a magic dpkg var that prevents it from using sigstop */ @@ -1519,12 +1543,9 @@ bool pkgDPkgPM::Go(int OutStatusFd) int const _dpkgin = fd[0]; close(fd[1]); // close the write end of the pipe - if(slave > 0) - close(slave); - // setups fds - sigemptyset(&sigmask); - sigprocmask(SIG_BLOCK,&sigmask,&original_sigmask); + sigemptyset(&d->sigmask); + sigprocmask(SIG_BLOCK,&d->sigmask,&d->original_sigmask); /* free vectors (and therefore memory) as we don't need the included data anymore */ for (std::vector::const_iterator p = Packages.begin(); @@ -1553,18 +1574,18 @@ bool pkgDPkgPM::Go(int OutStatusFd) // wait for input or output here FD_ZERO(&rfds); - if (master >= 0 && !d->stdin_is_dev_null) + if (d->master >= 0 && !d->stdin_is_dev_null) FD_SET(0, &rfds); FD_SET(_dpkgin, &rfds); - if(master >= 0) - FD_SET(master, &rfds); + if(d->master >= 0) + FD_SET(d->master, &rfds); tv.tv_sec = 1; tv.tv_nsec = 0; - select_ret = pselect(max(master, _dpkgin)+1, &rfds, NULL, NULL, - &tv, &original_sigmask); + select_ret = pselect(max(d->master, _dpkgin)+1, &rfds, NULL, NULL, + &tv, &d->original_sigmask); if (select_ret < 0 && (errno == EINVAL || errno == ENOSYS)) - select_ret = racy_pselect(max(master, _dpkgin)+1, &rfds, NULL, - NULL, &tv, &original_sigmask); + select_ret = racy_pselect(max(d->master, _dpkgin)+1, &rfds, NULL, + NULL, &tv, &d->original_sigmask); if (select_ret == 0) continue; else if (select_ret < 0 && errno == EINTR) @@ -1575,10 +1596,10 @@ bool pkgDPkgPM::Go(int OutStatusFd) continue; } - if(master >= 0 && FD_ISSET(master, &rfds)) - DoTerminalPty(master); - if(master >= 0 && FD_ISSET(0, &rfds)) - DoStdin(master); + if(d->master >= 0 && FD_ISSET(d->master, &rfds)) + DoTerminalPty(d->master); + if(d->master >= 0 && FD_ISSET(0, &rfds)) + DoStdin(d->master); if(FD_ISSET(_dpkgin, &rfds)) DoDpkgStatusFd(_dpkgin, OutStatusFd); } @@ -1589,13 +1610,6 @@ bool pkgDPkgPM::Go(int OutStatusFd) signal(SIGINT,old_SIGINT); signal(SIGHUP,old_SIGHUP); - - if(master >= 0) - { - tcsetattr(0, TCSAFLUSH, &tt); - close(master); - } - // Check for an error code. if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0) { @@ -1632,6 +1646,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) SendTerminalProgress(100); CleanupTerminal(); + StopPtyMagic(); if (pkgPackageManager::SigINTStop) _error->Warning(_("Operation was interrupted before it could finish")); diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index 1a58e1af5..5551b4383 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -95,6 +95,9 @@ class pkgDPkgPM : public pkgPackageManager // dpkg log bool OpenLog(); bool CloseLog(); + + void StartPtyMagic(); + void StopPtyMagic(); // input processing void DoStdin(int master); -- cgit v1.2.3 From bd5f39b34cc0e8cebbe9103f569d4d903e75bd2b Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 31 Oct 2013 08:23:12 +0100 Subject: restore ABI and prepare next ABI via #if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) --- apt-pkg/deb/dpkgpm.cc | 17 +++++++++++++++++ apt-pkg/deb/dpkgpm.h | 7 +++++++ apt-pkg/install-progress.cc | 22 ++++++++++++++++++++++ apt-pkg/install-progress.h | 3 +++ apt-pkg/packagemanager.cc | 36 ++++++++++++++++++++++++++++++------ apt-pkg/packagemanager.h | 15 ++++++++++++++- 6 files changed, 93 insertions(+), 7 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 98fb7581a..b252c02eb 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1000,6 +1000,19 @@ void pkgDPkgPM::BuildPackagesProgressMap() } } /*}}}*/ +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13) +bool pkgDPkgPM::Go(int StatusFd) +{ + APT::Progress::PackageManager *progress = NULL; + if (StatusFd == -1) + progress = APT::Progress::PackageManagerProgressFactory(); + else + progress = new APT::Progress::PackageManagerProgressFd(StatusFd); + + return GoNoABIBreak(progress); +} +#endif + // DPkgPM::Go - Run the sequence /*{{{*/ // --------------------------------------------------------------------- /* This globs the operations and calls dpkg @@ -1009,7 +1022,11 @@ void pkgDPkgPM::BuildPackagesProgressMap() * through to human readable (and i10n-able) * names and calculates a percentage for each step. */ +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) +#else +bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress) +#endif { pkgPackageManager::SigINTStop = false; d->progress = progress; diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index 5f00eee5d..4494bbae3 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -15,6 +15,7 @@ #include #include #include +#include #ifndef APT_8_CLEANER_HEADERS using std::vector; @@ -112,7 +113,13 @@ class pkgDPkgPM : public pkgPackageManager virtual bool Configure(PkgIterator Pkg); virtual bool Remove(PkgIterator Pkg,bool Purge = false); +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) virtual bool Go(APT::Progress::PackageManager *progress); +#else + virtual bool Go(int StatusFd=-1); + bool GoNoABIBreak(APT::Progress::PackageManager *progress); +#endif + virtual void Reset(); public: diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc index 9d0d4e3f1..a9146f27d 100644 --- a/apt-pkg/install-progress.cc +++ b/apt-pkg/install-progress.cc @@ -13,6 +13,28 @@ namespace APT { namespace Progress { +PackageManager* PackageManagerProgressFactory() +{ + // select the right progress + int status_fd = _config->FindI("APT::Status-Fd", -1); + int status_deb822_fd = _config->FindI("APT::Status-deb822-Fd", -1); + + APT::Progress::PackageManager *progress = NULL; + if (status_deb822_fd > 0) + progress = new APT::Progress::PackageManagerProgressDeb822Fd( + status_deb822_fd); + else if (status_fd > 0) + progress = new APT::Progress::PackageManagerProgressFd(status_fd); + else if(_config->FindB("Dpkg::Progress-Fancy", false) == true) + progress = new APT::Progress::PackageManagerFancy(); + else if (_config->FindB("Dpkg::Progress", + _config->FindB("DpkgPM::Progress", false)) == true) + progress = new APT::Progress::PackageManagerText(); + else + progress = new APT::Progress::PackageManager(); + return progress; +} + bool PackageManager::StatusChanged(std::string PackageName, unsigned int StepsDone, unsigned int TotalSteps, diff --git a/apt-pkg/install-progress.h b/apt-pkg/install-progress.h index 9c31eac92..050954bb5 100644 --- a/apt-pkg/install-progress.h +++ b/apt-pkg/install-progress.h @@ -8,6 +8,9 @@ namespace APT { namespace Progress { + class PackageManager; + PackageManager* PackageManagerProgressFactory(); + class PackageManager { private: diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index a2079a2e4..3fdd9b637 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -1030,15 +1030,16 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() // PM::DoInstallPostFork - compat /*{{{*/ // --------------------------------------------------------------------- /*}}}*/ +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) pkgPackageManager::OrderResult pkgPackageManager::DoInstallPostFork(int statusFd) { - APT::Progress::PackageManager *progress = new - APT::Progress::PackageManagerProgressFd(statusFd); - pkgPackageManager::OrderResult res = DoInstallPostFork(progress); - delete progress; - return res; - } + APT::Progress::PackageManager *progress = new + APT::Progress::PackageManagerProgressFd(statusFd); + pkgPackageManager::OrderResult res = DoInstallPostFork(progress); + delete progress; + return res; +} /*}}}*/ // PM::DoInstallPostFork - Does install part that happens after the fork /*{{{*/ // --------------------------------------------------------------------- @@ -1051,10 +1052,22 @@ pkgPackageManager::DoInstallPostFork(APT::Progress::PackageManager *progress) return Res; }; +#else +pkgPackageManager::OrderResult +pkgPackageManager::DoInstallPostFork(int statusFd) +{ + bool goResult = Go(statusFd); + if(goResult == false) + return Failed; + + return Res; +} +#endif /*}}}*/ // PM::DoInstall - Does the installation /*{{{*/ // --------------------------------------------------------------------- /* compat */ +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) pkgPackageManager::OrderResult pkgPackageManager::DoInstall(int statusFd) { @@ -1064,11 +1077,21 @@ pkgPackageManager::DoInstall(int statusFd) delete progress; return res; } +#else +pkgPackageManager::OrderResult pkgPackageManager::DoInstall(int statusFd) +{ + if(DoInstallPreFork() == Failed) + return Failed; + + return DoInstallPostFork(statusFd); +} +#endif /*}}}*/ // PM::DoInstall - Does the installation /*{{{*/ // --------------------------------------------------------------------- /* This uses the filenames in FileNames and the information in the DepCache to perform the installation of packages.*/ +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) pkgPackageManager::OrderResult pkgPackageManager::DoInstall(APT::Progress::PackageManager *progress) { @@ -1077,4 +1100,5 @@ pkgPackageManager::DoInstall(APT::Progress::PackageManager *progress) return DoInstallPostFork(progress); } +#endif /*}}}*/ diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index 8ffac2f13..a5c58e4a7 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -87,7 +88,12 @@ class pkgPackageManager : protected pkgCache::Namespace virtual bool Install(PkgIterator /*Pkg*/,std::string /*File*/) {return false;}; virtual bool Configure(PkgIterator /*Pkg*/) {return false;}; virtual bool Remove(PkgIterator /*Pkg*/,bool /*Purge*/=false) {return false;}; +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) virtual bool Go(APT::Progress::PackageManager *progress) {return true;}; +#else + virtual bool Go(int StatusFd=-1) {return true;}; +#endif + virtual void Reset() {}; // the result of the operation @@ -100,9 +106,13 @@ class pkgPackageManager : protected pkgCache::Namespace pkgRecords *Recs); // Do the installation +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) OrderResult DoInstall(APT::Progress::PackageManager *progress); // compat __deprecated OrderResult DoInstall(int statusFd=-1); +#else + OrderResult DoInstall(int statusFd=-1); +#endif // stuff that needs to be done before the fork() of a library that // uses apt @@ -110,11 +120,14 @@ class pkgPackageManager : protected pkgCache::Namespace Res = OrderInstall(); return Res; }; - +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) // stuff that needs to be done after the fork OrderResult DoInstallPostFork(APT::Progress::PackageManager *progress); // compat __deprecated OrderResult DoInstallPostFork(int statusFd=-1); +#else + OrderResult DoInstallPostFork(int statusFd=-1); +#endif // ? bool FixMissing(); -- cgit v1.2.3 From c5f0d8e6f8d338727b2b6bc4be0e482082398014 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 31 Oct 2013 17:08:20 +0100 Subject: fix some more ABI issues, abicheck is happy now --- apt-pkg/deb/dpkgpm.h | 9 +++++++++ apt-pkg/packagemanager.h | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index 4494bbae3..50b5d609b 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -107,6 +107,15 @@ class pkgDPkgPM : public pkgPackageManager void DoTerminalPty(int master); void DoDpkgStatusFd(int statusfd); void ProcessDpkgStatusLine(char *line); +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13) + void DoDpkgStatusFd(int statusfd, int unused) { + DoDpkgStatusFd(statusfd); + } + void ProcessDpkgStatusLine(int unused, char *line) { + ProcessDpkgStatusLine(line); + } +#endif + // The Actuall installation implementation virtual bool Install(PkgIterator Pkg,std::string File); diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index a5c58e4a7..853b9bac8 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -91,7 +91,7 @@ class pkgPackageManager : protected pkgCache::Namespace #if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) virtual bool Go(APT::Progress::PackageManager *progress) {return true;}; #else - virtual bool Go(int StatusFd=-1) {return true;}; + virtual bool Go(int statusFd=-1) {return true;}; #endif virtual void Reset() {}; -- cgit v1.2.3 From e45c4617e496b49f8d7225546a751022f246a2f3 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 31 Oct 2013 22:55:38 +0100 Subject: add new pid_t ExecFork(std::set KeepFDs) to get rid of the super ugly APT::Keep-Fds hack and also add a new PackageManagerProgressFd::StartDpkg() progress state --- apt-pkg/contrib/fileutl.cc | 33 +++++++++++++++++++-------------- apt-pkg/contrib/fileutl.h | 2 ++ apt-pkg/deb/dpkgpm.cc | 26 ++++++++++++++------------ apt-pkg/install-progress.cc | 6 +----- apt-pkg/install-progress.h | 8 +++++++- 5 files changed, 43 insertions(+), 32 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 0261119ba..2347ef140 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -766,6 +766,25 @@ bool WaitFd(int Fd,bool write,unsigned long timeout) child, it fixes up the important signals and nukes all of the fds, otherwise acts like normal fork. */ pid_t ExecFork() +{ + set KeepFDs; + + Configuration::Item const *Opts = _config->Tree("APT::Keep-Fds"); + if (Opts != 0 && Opts->Child != 0) + { + Opts = Opts->Child; + for (; Opts != 0; Opts = Opts->Next) + { + if (Opts->Value.empty() == true) + continue; + int fd = atoi(Opts->Value.c_str()); + KeepFDs.insert(fd); + } + } + return ExecFork(KeepFDs); +} + +pid_t ExecFork(std::set KeepFDs) { // Fork off the process pid_t Process = fork(); @@ -786,20 +805,6 @@ pid_t ExecFork() signal(SIGCONT,SIG_DFL); signal(SIGTSTP,SIG_DFL); - set KeepFDs; - Configuration::Item const *Opts = _config->Tree("APT::Keep-Fds"); - if (Opts != 0 && Opts->Child != 0) - { - Opts = Opts->Child; - for (; Opts != 0; Opts = Opts->Next) - { - if (Opts->Value.empty() == true) - continue; - int fd = atoi(Opts->Value.c_str()); - KeepFDs.insert(fd); - } - } - // Close all of our FDs - just in case for (int K = 3; K != 40; K++) { diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index decd64d9d..63a999c30 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -26,6 +26,7 @@ #include #include +#include #include @@ -182,6 +183,7 @@ void SetCloseExec(int Fd,bool Close); void SetNonBlock(int Fd,bool Block); bool WaitFd(int Fd,bool write = false,unsigned long timeout = 0); pid_t ExecFork(); +pid_t ExecFork(std::set keep_fds); bool ExecWait(pid_t Pid,const char *Name,bool Reap = false); // File string manipulators diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index d1b11098c..26d79dbb1 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -416,17 +416,20 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) unsigned int InfoFD = _config->FindI(OptSec + "::InfoFD", STDIN_FILENO); // Create the pipes + std::set KeepFDs; int Pipes[2]; if (pipe(Pipes) != 0) return _error->Errno("pipe","Failed to create IPC pipe to subprocess"); if (InfoFD != (unsigned)Pipes[0]) SetCloseExec(Pipes[0],true); else - _config->Set("APT::Keep-Fds::", Pipes[0]); + KeepFDs.insert(Pipes[0]); + + SetCloseExec(Pipes[1],true); // Purified Fork for running the script - pid_t Process = ExecFork(); + pid_t Process = ExecFork(KeepFDs); if (Process == 0) { // Setup the FDs @@ -448,8 +451,6 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) execv(Args[0],(char **)Args); _exit(100); } - if (InfoFD == (unsigned)Pipes[0]) - _config->Clear("APT::Keep-Fds", Pipes[0]); close(Pipes[0]); FILE *F = fdopen(Pipes[1],"w"); if (F == 0) @@ -1375,11 +1376,14 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress) // ignore SIGHUP as well (debian #463030) sighandler_t old_SIGHUP = signal(SIGHUP,SIG_IGN); - pid_t Child = ExecFork(); - // This is the child + // now run dpkg + d->progress->StartDpkg(); + std::set KeepFDs; + KeepFDs.insert(fd[1]); + pid_t Child = ExecFork(KeepFDs); if (Child == 0) { - + // This is the child if(d->slave >= 0 && d->master >= 0) { setsid(); @@ -1425,9 +1429,6 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress) if (_config->FindB("DPkg::UseIoNice", false) == true) ionice(Child); - // clear the Keep-Fd again - _config->Clear("APT::Keep-Fds",fd[1]); - // Wait for dpkg int Status = 0; @@ -1471,13 +1472,14 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress) FD_SET(_dpkgin, &rfds); if(d->master >= 0) FD_SET(d->master, &rfds); - tv.tv_sec = 1; - tv.tv_nsec = 0; + tv.tv_sec = 0; + tv.tv_nsec = d->progress->GetPulseInterval(); select_ret = pselect(max(d->master, _dpkgin)+1, &rfds, NULL, NULL, &tv, &d->original_sigmask); if (select_ret < 0 && (errno == EINVAL || errno == ENOSYS)) select_ret = racy_pselect(max(d->master, _dpkgin)+1, &rfds, NULL, NULL, &tv, &d->original_sigmask); + d->progress->Pulse(); if (select_ret == 0) continue; else if (select_ret < 0 && errno == EINTR) diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc index a9146f27d..79660b29e 100644 --- a/apt-pkg/install-progress.cc +++ b/apt-pkg/install-progress.cc @@ -63,7 +63,7 @@ void PackageManagerProgressFd::WriteToStatusFd(std::string s) FileFd::Write(OutStatusFd, s.c_str(), s.size()); } -void PackageManagerProgressFd::Start() +void PackageManagerProgressFd::StartDpkg() { if(OutStatusFd <= 0) return; @@ -83,8 +83,6 @@ void PackageManagerProgressFd::Start() void PackageManagerProgressFd::Stop() { - // clear the Keep-Fd again - _config->Clear("APT::Keep-Fds", OutStatusFd); } void PackageManagerProgressFd::Error(std::string PackageName, @@ -168,8 +166,6 @@ void PackageManagerProgressDeb822Fd::Start() void PackageManagerProgressDeb822Fd::Stop() { - // clear the Keep-Fd again - _config->Clear("APT::Keep-Fds", OutStatusFd); } void PackageManagerProgressDeb822Fd::Error(std::string PackageName, diff --git a/apt-pkg/install-progress.h b/apt-pkg/install-progress.h index 050954bb5..5291039d8 100644 --- a/apt-pkg/install-progress.h +++ b/apt-pkg/install-progress.h @@ -27,9 +27,15 @@ namespace Progress { : percentage(0.0), last_reported_progress(-1) {}; virtual ~PackageManager() {}; + /* Global Start/Stop */ virtual void Start() {}; virtual void Stop() {}; + /* When dpkg is invoked (may happen multiple times for each + * install/remove block + */ + virtual void StartDpkg() {}; + virtual pid_t fork() {return fork(); }; virtual void Pulse() {}; @@ -62,7 +68,7 @@ namespace Progress { public: PackageManagerProgressFd(int progress_fd); - virtual void Start(); + virtual void StartDpkg(); virtual void Stop(); virtual bool StatusChanged(std::string PackageName, -- cgit v1.2.3 From 790d41f6372871e527f3fc9da66d049937b4c780 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 31 Oct 2013 23:00:11 +0100 Subject: use StartDpkg() in PackageManagerProgressDeb822Fd as well --- apt-pkg/install-progress.cc | 2 +- apt-pkg/install-progress.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc index 79660b29e..f76fc88c2 100644 --- a/apt-pkg/install-progress.cc +++ b/apt-pkg/install-progress.cc @@ -149,7 +149,7 @@ void PackageManagerProgressDeb822Fd::WriteToStatusFd(std::string s) FileFd::Write(OutStatusFd, s.c_str(), s.size()); } -void PackageManagerProgressDeb822Fd::Start() +void PackageManagerProgressDeb822Fd::StartDpkg() { // FIXME: use SetCloseExec here once it taught about throwing // exceptions instead of doing _exit(100) on failure diff --git a/apt-pkg/install-progress.h b/apt-pkg/install-progress.h index 5291039d8..d721c6373 100644 --- a/apt-pkg/install-progress.h +++ b/apt-pkg/install-progress.h @@ -97,7 +97,7 @@ namespace Progress { public: PackageManagerProgressDeb822Fd(int progress_fd); - virtual void Start(); + virtual void StartDpkg(); virtual void Stop(); virtual bool StatusChanged(std::string PackageName, -- cgit v1.2.3 From bc37330b76f56a556ab1ddcd4e6cfb72640f5764 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 31 Oct 2013 23:24:41 +0100 Subject: setup LINES in apt-pkg/install-progress.cc --- apt-pkg/install-progress.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc index f76fc88c2..b341fe686 100644 --- a/apt-pkg/install-progress.cc +++ b/apt-pkg/install-progress.cc @@ -235,6 +235,11 @@ void PackageManagerFancy::SetupTerminalScrollArea(int nr_rows) static const char *move_cursor_up = "\033[1A"; std::cout << move_cursor_up; + // setup env for (hopefully!) ncurses + string s; + strprintf(s, "%i", nr_rows); + setenv("LINES", s.c_str(), 1); + std::flush(std::cout); } -- cgit v1.2.3 From 61f954bff040809e7ab57b3adec2fe95339ffb94 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 1 Nov 2013 10:42:49 +0100 Subject: small documentation updates --- apt-pkg/algorithms.h | 2 +- apt-pkg/contrib/fileutl.cc | 3 ++- apt-pkg/install-progress.cc | 4 ++++ 3 files changed, 7 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h index 80f6578eb..5a9a77415 100644 --- a/apt-pkg/algorithms.h +++ b/apt-pkg/algorithms.h @@ -40,11 +40,11 @@ #ifndef APT_8_CLEANER_HEADERS #include -// include pkg{DistUpgrade,AllUpgrade,MiniizeUpgrade} here for compatiblity using std::ostream; #endif #ifndef APT_9_CLEANER_HEADERS +// include pkg{DistUpgrade,AllUpgrade,MiniizeUpgrade} here for compatiblity #include #include #endif diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 2347ef140..d2be276c7 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -769,6 +769,7 @@ pid_t ExecFork() { set KeepFDs; + // FIXME: remove looking at APT::Keep-Fds eventually, its a hack Configuration::Item const *Opts = _config->Tree("APT::Keep-Fds"); if (Opts != 0 && Opts->Child != 0) { @@ -806,7 +807,7 @@ pid_t ExecFork(std::set KeepFDs) signal(SIGTSTP,SIG_DFL); // Close all of our FDs - just in case - for (int K = 3; K != 40; K++) + for (int K = 3; K != sysconf(_SC_OPEN_MAX); K++) { if(KeepFDs.find(K) == KeepFDs.end()) fcntl(K,F_SETFD,FD_CLOEXEC); diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc index b341fe686..09b1bef9e 100644 --- a/apt-pkg/install-progress.cc +++ b/apt-pkg/install-progress.cc @@ -13,6 +13,10 @@ namespace APT { namespace Progress { + +/* Return a APT::Progress::PackageManager based on the global + * apt configuration (i.e. APT::Status-Fd and APT::Status-deb822-Fd) + */ PackageManager* PackageManagerProgressFactory() { // select the right progress -- cgit v1.2.3 From e6645b9fb9ba3a7ff7b6663af3f5e1bcb6f23d78 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 26 Nov 2013 10:32:21 +0100 Subject: add check when sources.list changed --- apt-pkg/contrib/hashes.cc | 25 +++++++++++++++++++++---- apt-pkg/contrib/hashes.h | 9 ++++++++- 2 files changed, 29 insertions(+), 5 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/hashes.cc b/apt-pkg/contrib/hashes.cc index e1a431823..b4c768db9 100644 --- a/apt-pkg/contrib/hashes.cc +++ b/apt-pkg/contrib/hashes.cc @@ -54,6 +54,26 @@ HashString::HashString(std::string StringedHash) /*{{{*/ } /*}}}*/ bool HashString::VerifyFile(std::string filename) const /*{{{*/ +{ + std::string fileHash = GetHashForFile(filename); + + if(_config->FindB("Debug::Hashes",false) == true) + std::clog << "HashString::VerifyFile: got: " << fileHash << " expected: " << toStr() << std::endl; + + return (fileHash == Hash); +} + /*}}}*/ +bool HashString::FromFile(std::string filename) /*{{{*/ +{ + // pick the strongest hash + if (Type == "") + Type = _SupportedHashes[0]; + + Hash = GetHashForFile(filename); + return true; +} + /*}}}*/ +std::string HashString::GetHashForFile(std::string filename) const /*{{{*/ { std::string fileHash; @@ -84,10 +104,7 @@ bool HashString::VerifyFile(std::string filename) const /*{{{*/ } Fd.Close(); - if(_config->FindB("Debug::Hashes",false) == true) - std::clog << "HashString::VerifyFile: got: " << fileHash << " expected: " << toStr() << std::endl; - - return (fileHash == Hash); + return fileHash; } /*}}}*/ const char** HashString::SupportedHashes() diff --git a/apt-pkg/contrib/hashes.h b/apt-pkg/contrib/hashes.h index 0c0b6c6a7..0a8bcd259 100644 --- a/apt-pkg/contrib/hashes.h +++ b/apt-pkg/contrib/hashes.h @@ -36,7 +36,10 @@ class HashString protected: std::string Type; std::string Hash; - static const char * _SupportedHashes[10]; + static const char* _SupportedHashes[10]; + + // internal helper + std::string GetHashForFile(std::string filename) const; public: HashString(std::string Type, std::string Hash); @@ -49,6 +52,10 @@ class HashString // verify the given filename against the currently loaded hash bool VerifyFile(std::string filename) const; + // generate a hash string from the given filename + bool FromFile(std::string filename); + + // helper std::string toStr() const; // convert to str as "type:hash" bool empty() const; -- cgit v1.2.3 From 96ae6de5d3d5ae31100079c78fffc5ebc4a0b81c Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 28 Nov 2013 17:08:53 +0100 Subject: fix regression that APT::Keep-Fds is not honored (closes: #730490) --- apt-pkg/contrib/fileutl.cc | 26 ++++++++++++++++++-------- apt-pkg/contrib/fileutl.h | 1 + apt-pkg/deb/dpkgpm.cc | 2 ++ 3 files changed, 21 insertions(+), 8 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index d2be276c7..3a6bdfe2e 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -760,16 +760,13 @@ bool WaitFd(int Fd,bool write,unsigned long timeout) return true; } /*}}}*/ -// ExecFork - Magical fork that sanitizes the context before execing /*{{{*/ +// MergeKeepFdsFromConfiguration - Merge APT::Keep-Fds configuration /*{{{*/ // --------------------------------------------------------------------- -/* This is used if you want to cleanse the environment for the forked - child, it fixes up the important signals and nukes all of the fds, - otherwise acts like normal fork. */ -pid_t ExecFork() +/* This is used to merge the APT::Keep-Fds with the provided KeepFDs + * set. + */ +void MergeKeepFdsFromConfiguration(std::set &KeepFDs) { - set KeepFDs; - - // FIXME: remove looking at APT::Keep-Fds eventually, its a hack Configuration::Item const *Opts = _config->Tree("APT::Keep-Fds"); if (Opts != 0 && Opts->Child != 0) { @@ -782,6 +779,19 @@ pid_t ExecFork() KeepFDs.insert(fd); } } +} + /*}}}*/ +// ExecFork - Magical fork that sanitizes the context before execing /*{{{*/ +// --------------------------------------------------------------------- +/* This is used if you want to cleanse the environment for the forked + child, it fixes up the important signals and nukes all of the fds, + otherwise acts like normal fork. */ +pid_t ExecFork() +{ + set KeepFDs; + // we need to merge the Keep-Fds as external tools like + // debconf-apt-progress use it + MergeKeepFdsFromConfiguration(KeepFDs); return ExecFork(KeepFDs); } diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index 63a999c30..e9a9aab28 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -184,6 +184,7 @@ void SetNonBlock(int Fd,bool Block); bool WaitFd(int Fd,bool write = false,unsigned long timeout = 0); pid_t ExecFork(); pid_t ExecFork(std::set keep_fds); +void MergeKeepFdsFromConfiguration(std::set &keep_fds); bool ExecWait(pid_t Pid,const char *Name,bool Reap = false); // File string manipulators diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 26d79dbb1..01c6242dc 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -417,6 +417,7 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) // Create the pipes std::set KeepFDs; + MergeKeepFdsFromConfiguration(KeepFDs); int Pipes[2]; if (pipe(Pipes) != 0) return _error->Errno("pipe","Failed to create IPC pipe to subprocess"); @@ -1380,6 +1381,7 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress) d->progress->StartDpkg(); std::set KeepFDs; KeepFDs.insert(fd[1]); + MergeKeepFdsFromConfiguration(KeepFDs); pid_t Child = ExecFork(KeepFDs); if (Child == 0) { -- cgit v1.2.3 From cf993341c2067ee091cfd51e5da0e237babce171 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 29 Nov 2013 08:35:05 +0100 Subject: add "APT::String::Endswith" and automatic adding of ".list" in apt edit-source --- apt-pkg/contrib/strutl.cc | 8 ++++++++ apt-pkg/contrib/strutl.h | 1 + 2 files changed, 9 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 9f794927d..962112854 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -49,6 +49,14 @@ std::string Strip(const std::string &s) size_t end = s.find_last_not_of(" \t\n"); return s.substr(start, end-start+1); } + +bool Endswith(const std::string &s, const std::string &end) +{ + if (end.size() > s.size()) + return false; + return (s.substr(s.size() - end.size(), s.size()) == end); +} + } } /*}}}*/ diff --git a/apt-pkg/contrib/strutl.h b/apt-pkg/contrib/strutl.h index c8fc317c0..8d746f10e 100644 --- a/apt-pkg/contrib/strutl.h +++ b/apt-pkg/contrib/strutl.h @@ -36,6 +36,7 @@ using std::ostream; namespace APT { namespace String { std::string Strip(const std::string &s); + bool Endswith(const std::string &s, const std::string &ending); }; }; -- cgit v1.2.3 From 2f5ed336109d11e06d08bedef6b37d6597c4c09c Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 29 Nov 2013 17:10:35 +0100 Subject: fix crash when SetCandidateRelease is used --- apt-pkg/depcache.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index a06789cdf..f9c891c86 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1522,7 +1522,7 @@ bool pkgDepCache::SetCandidateRelease(pkgCache::VerIterator TargetVer, if (itsFine == false) { // change the candidate - Changed.push_back(make_pair(oldCand, TargetVer)); + Changed.push_back(make_pair(V, TargetVer)); if (SetCandidateRelease(V, TargetRel, Changed) == false) { if (stillOr == false) -- cgit v1.2.3 From 804d195655c48a448d576b2b196d18c2c816e824 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 29 Nov 2013 20:08:56 +0100 Subject: reset terminal on error (closes: #730795) --- apt-pkg/deb/dpkgpm.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 01c6242dc..49396c1c7 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1530,6 +1530,7 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress) if(stopOnError) { CloseLog(); + StopPtyMagic(); d->progress->Stop(); return false; } -- cgit v1.2.3 From 0cd4e696306af28f98c0f810ed18b052919205c8 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 29 Nov 2013 20:17:20 +0100 Subject: fix apport report writing (LP: #1254499) --- apt-pkg/deb/dpkgpm.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 49396c1c7..14333c3e7 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -201,7 +201,7 @@ pkgCache::VerIterator FindNowVersion(const pkgCache::PkgIterator &Pkg) // --------------------------------------------------------------------- /* */ pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) - : pkgPackageManager(Cache), PackagesDone(0), PackagesTotal(0) + : pkgPackageManager(Cache), pkgFailures(0), PackagesDone(0), PackagesTotal(0) { d = new pkgDPkgPMPrivate(); } -- cgit v1.2.3 From ad5051ef9da4e1f384237ecf1260e0cad95e0ea7 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 11 Oct 2013 13:07:01 +0200 Subject: truncating /dev/null to zero is always successful Calling truncate on /dev/null can happen by the download methods if they are instructed to download a file to /dev/null (as testcases are only interested in the status code, but do not support HEAD requests yet) So just ignore truncate calls on the /dev/null file as it is always empty anyway, so truncating to zero isn't a problem. Git-Dch: Ignore --- apt-pkg/contrib/fileutl.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 3a6bdfe2e..7fbe4d604 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -1545,6 +1545,9 @@ bool FileFd::Skip(unsigned long long Over) /* */ bool FileFd::Truncate(unsigned long long To) { + // truncating /dev/null is always successful - as we get an error otherwise + if (To == 0 && FileName == "/dev/null") + return true; #if defined HAVE_ZLIB || defined HAVE_BZ2 if (d != NULL && (d->gz != NULL || d->bz2 != NULL)) return FileFdError("Truncating compressed files is not implemented (%s)", FileName.c_str()); -- cgit v1.2.3 From 581b556830ba17dc8a9d3edb858a4fd8c1d2fb58 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 30 Nov 2013 13:10:33 +0100 Subject: merge ubuntus apport reporting changes to reduce diff apport reporting is still disabled by default, but it is available in Debian/experimental at the moment and a diff is not a good idea anyway. --- apt-pkg/deb/dpkgpm.cc | 59 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 5 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 14333c3e7..b4bfd1400 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1622,18 +1622,49 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) } // do not report out-of-memory failures - if(strstr(errormsg, strerror(ENOMEM)) != NULL) { + if(strstr(errormsg, strerror(ENOMEM)) != NULL || + strstr(errormsg, "failed to allocate memory") != NULL) { std::clog << _("No apport report written because the error message indicates a out of memory error") << std::endl; return; } - // do not report dpkg I/O errors - // XXX - this message is localized, but this only matches the English version. This is better than nothing. - if(strstr(errormsg, "short read in buffer_copy (")) { - std::clog << _("No apport report written because the error message indicates a dpkg I/O error") << std::endl; + // do not report bugs regarding inaccessible local files + if(strstr(errormsg, strerror(ENOENT)) != NULL || + strstr(errormsg, "cannot access archive") != NULL) { + std::clog << _("No apport report written because the error message indicates an issue on the local system") << std::endl; return; } + // do not report errors encountered when decompressing packages + if(strstr(errormsg, "--fsys-tarfile returned error exit status 2") != NULL) { + std::clog << _("No apport report written because the error message indicates an issue on the local system") << std::endl; + return; + } + + // do not report dpkg I/O errors, this is a format string, so we compare + // the prefix and the suffix of the error with the dpkg error message + vector io_errors; + io_errors.push_back(string("failed to read on buffer copy for %s")); + io_errors.push_back(string("failed in write on buffer copy for %s")); + io_errors.push_back(string("short read on buffer copy for %s")); + + for (vector::iterator I = io_errors.begin(); I != io_errors.end(); I++) + { + vector list = VectorizeString(dgettext("dpkg", (*I).c_str()), '%'); + if (list.size() > 1) { + // we need to split %s, VectorizeString only allows char so we need + // to kill the "s" manually + if (list[1].size() > 1) { + list[1].erase(0, 1); + if(strstr(errormsg, list[0].c_str()) && + strstr(errormsg, list[1].c_str())) { + std::clog << _("No apport report written because the error message indicates a dpkg I/O error") << std::endl; + return; + } + } + } + } + // get the pkgname and reportfile pkgname = flNotDir(pkgpath); pos = pkgname.find('_'); @@ -1721,6 +1752,24 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) if(log != NULL) { char buf[1024]; + while( fgets(buf, sizeof(buf), log) != NULL) + fprintf(report, " %s", buf); + fprintf(report, " \n"); + fclose(log); + } + } + + // attach history log it if we have it + string histfile_name = _config->FindFile("Dir::Log::History"); + if (!histfile_name.empty()) + { + FILE *log = NULL; + char buf[1024]; + + fprintf(report, "DpkgHistoryLog:\n"); + log = fopen(histfile_name.c_str(),"r"); + if(log != NULL) + { while( fgets(buf, sizeof(buf), log) != NULL) fprintf(report, " %s", buf); fclose(log); -- cgit v1.2.3 From 5555ef9850b7e66aa02d39bb7d624fdf3e43edb2 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 1 Dec 2013 00:05:34 +0100 Subject: drop old /var/state to /var/lib transition artefacts Regardless of when this transition was, it is so long ago that everyone who would still need this has a million other problems to deal with now so lets just drop this code. --- apt-pkg/init.cc | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/init.cc b/apt-pkg/init.cc index 76278921f..81b601a7f 100644 --- a/apt-pkg/init.cc +++ b/apt-pkg/init.cc @@ -44,16 +44,8 @@ bool pkgInitConfig(Configuration &Cnf) Cnf.CndSet("APT::Install-Suggests", false); Cnf.CndSet("Dir","/"); - // State + // State Cnf.CndSet("Dir::State","var/lib/apt/"); - - /* Just in case something goes horribly wrong, we can fall back to the - old /var/state paths.. */ - struct stat St; - if (stat("/var/lib/apt/.",&St) != 0 && - stat("/var/state/apt/.",&St) == 0) - Cnf.CndSet("Dir::State","var/state/apt/"); - Cnf.CndSet("Dir::State::lists","lists/"); Cnf.CndSet("Dir::State::cdroms","cdroms.list"); Cnf.CndSet("Dir::State::mirrors","mirrors/"); -- cgit v1.2.3 From 7014e1482942d00b66eb30061b0cf5d2a7b3ebf3 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 5 Dec 2013 08:11:11 +0100 Subject: * enable release based selection for deb-src (closes: 731102) --- apt-pkg/deb/debmetaindex.cc | 17 ++++++++++++++++- apt-pkg/deb/debmetaindex.h | 7 +++++++ apt-pkg/indexfile.h | 4 ++-- apt-pkg/indexrecords.cc | 5 +++++ apt-pkg/indexrecords.h | 1 + apt-pkg/metaindex.h | 24 +++++++++++++++++------- 6 files changed, 48 insertions(+), 10 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index b597b6f3c..504877558 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -1,4 +1,3 @@ -// ijones, walters #include #include @@ -72,6 +71,22 @@ string debReleaseIndex::MetaIndexURI(const char *Type) const return Res; } +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) +std::string debReleaseIndex::LocalFileName() const +{ + // see if we have a InRelease file + std::string PathInRelease = MetaIndexFile("InRelease"); + if (FileExists(PathInRelease)) + return PathInRelease; + + // and if not return the normal one + if (FileExists(PathInRelease)) + return MetaIndexFile("Release"); + + return ""; +} +#endif + string debReleaseIndex::IndexURISuffix(const char *Type, string const &Section, string const &Arch) const { string Res =""; diff --git a/apt-pkg/deb/debmetaindex.h b/apt-pkg/deb/debmetaindex.h index b9ecab97c..cef8d68f7 100644 --- a/apt-pkg/deb/debmetaindex.h +++ b/apt-pkg/deb/debmetaindex.h @@ -3,6 +3,7 @@ #define PKGLIB_DEBMETAINDEX_H #include +#include #include #include @@ -39,9 +40,15 @@ class debReleaseIndex : public metaIndex { virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false) const; std::vector * ComputeIndexTargets() const; std::string Info(const char *Type, std::string const &Section, std::string const &Arch="") const; + std::string MetaIndexInfo(const char *Type) const; std::string MetaIndexFile(const char *Types) const; std::string MetaIndexURI(const char *Type) const; + +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) + virtual std::string LocalFileName() const; +#endif + std::string IndexURI(const char *Type, std::string const &Section, std::string const &Arch="native") const; std::string IndexURISuffix(const char *Type, std::string const &Section, std::string const &Arch="native") const; std::string SourceIndexURI(const char *Type, const std::string &Section) const; diff --git a/apt-pkg/indexfile.h b/apt-pkg/indexfile.h index 1d34dc773..2d433b60a 100644 --- a/apt-pkg/indexfile.h +++ b/apt-pkg/indexfile.h @@ -78,10 +78,10 @@ class pkgIndexFile virtual bool Exists() const = 0; virtual bool HasPackages() const = 0; virtual unsigned long Size() const = 0; - virtual bool Merge(pkgCacheGenerator &/*Gen*/,OpProgress* /*Prog*/) const { return false; }; + virtual bool Merge(pkgCacheGenerator &Gen, OpProgress* Prog) const { return false; }; __deprecated virtual bool Merge(pkgCacheGenerator &Gen, OpProgress &Prog) const { return Merge(Gen, &Prog); }; - virtual bool MergeFileProvides(pkgCacheGenerator &/*Gen*/,OpProgress* /*Prog*/) const {return true;}; + virtual bool MergeFileProvides(pkgCacheGenerator &Gen,OpProgress* Prog) const {return true;}; __deprecated virtual bool MergeFileProvides(pkgCacheGenerator &Gen, OpProgress &Prog) const {return MergeFileProvides(Gen, &Prog);}; virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; diff --git a/apt-pkg/indexrecords.cc b/apt-pkg/indexrecords.cc index 8a72ca151..f8097c3c6 100644 --- a/apt-pkg/indexrecords.cc +++ b/apt-pkg/indexrecords.cc @@ -27,6 +27,11 @@ string indexRecords::GetDist() const return this->Dist; } +string indexRecords::GetSuite() const +{ + return this->Suite; +} + bool indexRecords::CheckDist(const string MaybeDist) const { return (this->Dist == MaybeDist diff --git a/apt-pkg/indexrecords.h b/apt-pkg/indexrecords.h index a98b939bc..d003ec0fa 100644 --- a/apt-pkg/indexrecords.h +++ b/apt-pkg/indexrecords.h @@ -46,6 +46,7 @@ class indexRecords virtual bool Load(std::string Filename); std::string GetDist() const; + std::string GetSuite() const; time_t GetValidUntil() const; virtual bool CheckDist(const std::string MaybeDist) const; std::string GetExpectedDist() const; diff --git a/apt-pkg/metaindex.h b/apt-pkg/metaindex.h index 5783735ff..18a90a29d 100644 --- a/apt-pkg/metaindex.h +++ b/apt-pkg/metaindex.h @@ -5,6 +5,7 @@ #include #include #include +#include #ifndef APT_8_CLEANER_HEADERS #include @@ -28,27 +29,36 @@ class metaIndex public: - // Various accessors virtual std::string GetURI() const {return URI;} virtual std::string GetDist() const {return Dist;} virtual const char* GetType() const {return Type;} + // interface to to query it +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) + // returns the path of the local file (or "" if its not available) + virtual std::string LocalFileName() const {return "";}; +#endif + // Interface for acquire - virtual std::string ArchiveURI(std::string const& /*File*/) const = 0; + virtual std::string ArchiveURI(std::string const& File) const = 0; virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false) const = 0; - virtual std::vector *GetIndexFiles() = 0; virtual bool IsTrusted() const = 0; - metaIndex(std::string const &URI, std::string const &Dist, char const * const Type) : - Indexes(NULL), Type(Type), URI(URI), Dist(Dist) { + metaIndex(std::string const &URI, std::string const &Dist, + char const * const Type) + : Indexes(NULL), Type(Type), URI(URI), Dist(Dist) + { + /* nothing */ } - virtual ~metaIndex() { + virtual ~metaIndex() + { if (Indexes == 0) return; - for (std::vector::iterator I = (*Indexes).begin(); I != (*Indexes).end(); ++I) + for (std::vector::iterator I = (*Indexes).begin(); + I != (*Indexes).end(); ++I) delete *I; delete Indexes; } -- cgit v1.2.3 From a537ce19f955f39ee62281bb12bc71a4c67bc635 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 2 Dec 2013 08:01:00 +0100 Subject: first version with test --- apt-pkg/sourcelist.cc | 46 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 0fd237cad..1261ebb52 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -242,16 +243,49 @@ bool pkgSourceList::Read(string File) /* */ bool pkgSourceList::ReadAppend(string File) { + // try reading as deb822 + // FIXME: proper error handling so that we do not error for good old-style + // sources + FileFd Fd(File, FileFd::ReadOnly); + pkgTagFile Sources(&Fd); + if (_error->PendingError() == false) + { + pkgTagSection Tags; + map Options; + int i=0; + while (Sources.Step(Tags) == true) + { + if(!Tags.Exists("Type")) + continue; + string const type = Tags.FindS("Type"); + Type *Parse = Type::GetType(type.c_str()); + if (Parse == 0) + return _error->Error(_("Type '%s' is not known on stanza %u in source list %s"),type.c_str(),i,File.c_str()); + + string URI = Tags.FindS("URL"); + if (!Parse->FixupURI(URI)) + return _error->Error(_("Malformed stanza %lu in source list %s (URI parse)"),i,File.c_str()); + string const Dist = Tags.FindS("Dist"); + string const Section = Tags.FindS("Section"); + // check if there are any options we support + const char* option_str[] = { + "arch", "arch+", "arch-", "trusted" }; + for (unsigned int j=0; j < sizeof(option_str)/sizeof(char*); j++) + if (Tags.Exists(option_str[j])) + Options[option_str[j]] = Tags.FindS(option_str[j]); + Parse->CreateItem(SrcList, URI, Dist, Section, Options); + i++; + } + // we are done + if(i>0) + return true; + } + // Open the stream for reading ifstream F(File.c_str(),ios::in /*| ios::nocreate*/); if (!F != 0) return _error->Errno("ifstream::ifstream",_("Opening %s"),File.c_str()); - -#if 0 // Now Reset() does this. - for (const_iterator I = SrcList.begin(); I != SrcList.end(); I++) - delete *I; - SrcList.erase(SrcList.begin(),SrcList.end()); -#endif + // CNC:2003-12-10 - 300 is too short. char Buffer[1024]; -- cgit v1.2.3 From 300b15e3456aff88b3016a8bac90a0ba8911db8f Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 2 Dec 2013 08:36:10 +0100 Subject: fix section adding --- apt-pkg/sourcelist.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 1261ebb52..4883e2fab 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -273,7 +273,16 @@ bool pkgSourceList::ReadAppend(string File) for (unsigned int j=0; j < sizeof(option_str)/sizeof(char*); j++) if (Tags.Exists(option_str[j])) Options[option_str[j]] = Tags.FindS(option_str[j]); - Parse->CreateItem(SrcList, URI, Dist, Section, Options); + + // now create one item per section + std::vector list; + if (Section.find(",")) + list = StringSplit(Section, ","); + else + list = StringSplit(Section, " "); + for (int i=0; i < list.size(); i++) + Parse->CreateItem(SrcList, URI, Dist, list[i], Options); + i++; } // we are done -- cgit v1.2.3 From e96e4e9cef3a0137b789117f72a93a8e9106562e Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 6 Dec 2013 15:54:12 +0100 Subject: Handle SIGWINCH in APT::Progress-Fancy=1 --- apt-pkg/deb/dpkgpm.h | 1 - apt-pkg/install-progress.cc | 32 +++++++++++++++++++++++++------- apt-pkg/install-progress.h | 9 ++++++--- 3 files changed, 31 insertions(+), 11 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index 06318d94f..02e12a6d9 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -89,7 +89,6 @@ class pkgDPkgPM : public pkgPackageManager const std::string &short_pkgname); // Terminal progress - void SetupTerminalScrollArea(int nr_scrolled_rows); void SendTerminalProgress(float percentage); // apport integration diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc index 09b1bef9e..b82b7efde 100644 --- a/apt-pkg/install-progress.cc +++ b/apt-pkg/install-progress.cc @@ -10,6 +10,7 @@ #include #include + namespace APT { namespace Progress { @@ -221,6 +222,14 @@ bool PackageManagerProgressDeb822Fd::StatusChanged(std::string PackageName, return true; } +int PackageManagerFancy::GetNumberTerminalRows() +{ + struct winsize win; + if(ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&win) != 0) + return -1; + + return win.ws_row; +} void PackageManagerFancy::SetupTerminalScrollArea(int nr_rows) { @@ -248,23 +257,32 @@ void PackageManagerFancy::SetupTerminalScrollArea(int nr_rows) } PackageManagerFancy::PackageManagerFancy() - : nr_terminal_rows(-1) { - struct winsize win; - if(ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&win) == 0) - { - nr_terminal_rows = win.ws_row; - } + // setup terminal size + old_SIGWINCH = signal(SIGWINCH, HandleSIGWINCH); +} + +PackageManagerFancy::~PackageManagerFancy() +{ + signal(SIGWINCH, old_SIGWINCH); +} + +void PackageManagerFancy::HandleSIGWINCH(int) +{ + int nr_terminal_rows = GetNumberTerminalRows(); + SetupTerminalScrollArea(nr_terminal_rows); } void PackageManagerFancy::Start() { + int nr_terminal_rows = GetNumberTerminalRows(); if (nr_terminal_rows > 0) SetupTerminalScrollArea(nr_terminal_rows); } void PackageManagerFancy::Stop() { + int nr_terminal_rows = GetNumberTerminalRows(); if (nr_terminal_rows > 0) { SetupTerminalScrollArea(nr_terminal_rows + 1); @@ -284,7 +302,7 @@ bool PackageManagerFancy::StatusChanged(std::string PackageName, HumanReadableAction)) return false; - int row = nr_terminal_rows; + int row = GetNumberTerminalRows(); static string save_cursor = "\033[s"; static string restore_cursor = "\033[u"; diff --git a/apt-pkg/install-progress.h b/apt-pkg/install-progress.h index d721c6373..4b7590983 100644 --- a/apt-pkg/install-progress.h +++ b/apt-pkg/install-progress.h @@ -3,7 +3,7 @@ #include #include - +#include namespace APT { namespace Progress { @@ -117,11 +117,14 @@ namespace Progress { class PackageManagerFancy : public PackageManager { protected: - int nr_terminal_rows; - void SetupTerminalScrollArea(int nr_rows); + static void SetupTerminalScrollArea(int nr_rows); + static int GetNumberTerminalRows(); + static void HandleSIGWINCH(int); + sighandler_t old_SIGWINCH; public: PackageManagerFancy(); + ~PackageManagerFancy(); virtual void Start(); virtual void Stop(); virtual bool StatusChanged(std::string PackageName, -- cgit v1.2.3 From 6f4478134e13070517c00960e7eb3793d142c0ea Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 9 Dec 2013 07:59:18 +0100 Subject: refactor deb822 reading into its own function --- apt-pkg/sourcelist.cc | 49 +++++++++++++++++++++++++++++++++---------------- apt-pkg/sourcelist.h | 5 ++++- 2 files changed, 37 insertions(+), 17 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 4883e2fab..c28cf0127 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -238,21 +238,15 @@ bool pkgSourceList::Read(string File) return ReadAppend(File); } /*}}}*/ -// SourceList::ReadAppend - Parse a sourcelist file /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool pkgSourceList::ReadAppend(string File) + +// FIXME: move into pkgSourceList::Type::ParseFile() +bool pkgSourceList::ParseFileDeb822(FileFd &Fd) { - // try reading as deb822 - // FIXME: proper error handling so that we do not error for good old-style - // sources - FileFd Fd(File, FileFd::ReadOnly); - pkgTagFile Sources(&Fd); - if (_error->PendingError() == false) - { pkgTagSection Tags; map Options; - int i=0; + unsigned int i=0; + + pkgTagFile Sources(&Fd); while (Sources.Step(Tags) == true) { if(!Tags.Exists("Type")) @@ -260,11 +254,11 @@ bool pkgSourceList::ReadAppend(string File) string const type = Tags.FindS("Type"); Type *Parse = Type::GetType(type.c_str()); if (Parse == 0) - return _error->Error(_("Type '%s' is not known on stanza %u in source list %s"),type.c_str(),i,File.c_str()); + return _error->Error(_("Type '%s' is not known on stanza %u in source list %s"),type.c_str(),i,Fd.Name().c_str()); string URI = Tags.FindS("URL"); if (!Parse->FixupURI(URI)) - return _error->Error(_("Malformed stanza %lu in source list %s (URI parse)"),i,File.c_str()); + return _error->Error(_("Malformed stanza %u in source list %s (URI parse)"),i,Fd.Name().c_str()); string const Dist = Tags.FindS("Dist"); string const Section = Tags.FindS("Section"); // check if there are any options we support @@ -280,16 +274,39 @@ bool pkgSourceList::ReadAppend(string File) list = StringSplit(Section, ","); else list = StringSplit(Section, " "); - for (int i=0; i < list.size(); i++) - Parse->CreateItem(SrcList, URI, Dist, list[i], Options); + for (std::vector::const_iterator I = list.begin(); + I != list.end(); I++) + Parse->CreateItem(SrcList, URI, Dist, (*I), Options); i++; } + // we are done if(i>0) return true; + + return false; +} + + +// SourceList::ReadAppend - Parse a sourcelist file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgSourceList::ReadAppend(string File) +{ + // *first* try reading as deb822 + // FIXME: proper error handling so that we do not error for good old-style + // sources + FileFd Fd(File, FileFd::ReadOnly); + if (_error->PendingError() == false) + { + if (ParseFileDeb822(Fd)) + return true; } + + // *then* read as old-style sources.list + // Open the stream for reading ifstream F(File.c_str(),ios::in /*| ios::nocreate*/); if (!F != 0) diff --git a/apt-pkg/sourcelist.h b/apt-pkg/sourcelist.h index 02e27101a..af3f4f5c6 100644 --- a/apt-pkg/sourcelist.h +++ b/apt-pkg/sourcelist.h @@ -75,7 +75,10 @@ class pkgSourceList protected: std::vector SrcList; - + + // FIXME: move int Type with the next ABI break + bool ParseFileDeb822(FileFd &Fd); + public: bool ReadMainList(); -- cgit v1.2.3 From 1fa78a8a3730633be662df07f7aec8f4c3dcc766 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 9 Dec 2013 08:21:53 +0100 Subject: more refactor --- apt-pkg/sourcelist.cc | 133 +++++++++++++++++++++++++------------------------- apt-pkg/sourcelist.h | 4 +- 2 files changed, 69 insertions(+), 68 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index c28cf0127..714918bc1 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -160,7 +160,6 @@ bool pkgSourceList::Type::ParseLine(vector &List, return true; } /*}}}*/ - // SourceList::pkgSourceList - Constructors /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -182,7 +181,6 @@ pkgSourceList::~pkgSourceList() delete *I; } /*}}}*/ - /*}}}*/ // SourceList::ReadMainList - Read the main source list from etc /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -217,7 +215,6 @@ bool pkgSourceList::ReadMainList() return Res; } /*}}}*/ -// CNC:2003-03-03 - Needed to preserve backwards compatibility. // SourceList::Reset - Clear the sourcelist contents /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -228,7 +225,6 @@ void pkgSourceList::Reset() SrcList.erase(SrcList.begin(),SrcList.end()); } /*}}}*/ -// CNC:2003-03-03 - Function moved to ReadAppend() and Reset(). // SourceList::Read - Parse the sourcelist file /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -238,75 +234,21 @@ bool pkgSourceList::Read(string File) return ReadAppend(File); } /*}}}*/ - -// FIXME: move into pkgSourceList::Type::ParseFile() -bool pkgSourceList::ParseFileDeb822(FileFd &Fd) -{ - pkgTagSection Tags; - map Options; - unsigned int i=0; - - pkgTagFile Sources(&Fd); - while (Sources.Step(Tags) == true) - { - if(!Tags.Exists("Type")) - continue; - string const type = Tags.FindS("Type"); - Type *Parse = Type::GetType(type.c_str()); - if (Parse == 0) - return _error->Error(_("Type '%s' is not known on stanza %u in source list %s"),type.c_str(),i,Fd.Name().c_str()); - - string URI = Tags.FindS("URL"); - if (!Parse->FixupURI(URI)) - return _error->Error(_("Malformed stanza %u in source list %s (URI parse)"),i,Fd.Name().c_str()); - string const Dist = Tags.FindS("Dist"); - string const Section = Tags.FindS("Section"); - // check if there are any options we support - const char* option_str[] = { - "arch", "arch+", "arch-", "trusted" }; - for (unsigned int j=0; j < sizeof(option_str)/sizeof(char*); j++) - if (Tags.Exists(option_str[j])) - Options[option_str[j]] = Tags.FindS(option_str[j]); - - // now create one item per section - std::vector list; - if (Section.find(",")) - list = StringSplit(Section, ","); - else - list = StringSplit(Section, " "); - for (std::vector::const_iterator I = list.begin(); - I != list.end(); I++) - Parse->CreateItem(SrcList, URI, Dist, (*I), Options); - - i++; - } - - // we are done - if(i>0) - return true; - - return false; -} - - // SourceList::ReadAppend - Parse a sourcelist file /*{{{*/ // --------------------------------------------------------------------- /* */ bool pkgSourceList::ReadAppend(string File) { - // *first* try reading as deb822 - // FIXME: proper error handling so that we do not error for good old-style - // sources - FileFd Fd(File, FileFd::ReadOnly); - if (_error->PendingError() == false) - { - if (ParseFileDeb822(Fd)) + if (ParseFileDeb822(File)) return true; - } - - - // *then* read as old-style sources.list + return ParseFileOldStyle(File); +} +// SourceList::ReadFileOldStyle - Read Traditional style sources.list /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgSourceList::ParseFileOldStyle(string File) +{ // Open the stream for reading ifstream F(File.c_str(),ios::in /*| ios::nocreate*/); if (!F != 0) @@ -358,6 +300,65 @@ bool pkgSourceList::ReadAppend(string File) return true; } /*}}}*/ +// SourceList::ParseFileDeb822 - Parse deb822 style sources.list /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgSourceList::ParseFileDeb822(string File) +{ + // FIXME: proper error handling so that we do not error for good old-style + // sources + FileFd Fd(File, FileFd::ReadOnly); + if (_error->PendingError() == true) + { + return false; + } + + pkgTagSection Tags; + map Options; + unsigned int i=0; + + pkgTagFile Sources(&Fd); + while (Sources.Step(Tags) == true) + { + if(!Tags.Exists("Type")) + continue; + string const type = Tags.FindS("Type"); + Type *Parse = Type::GetType(type.c_str()); + if (Parse == 0) + return _error->Error(_("Type '%s' is not known on stanza %u in source list %s"),type.c_str(),i,Fd.Name().c_str()); + + string URI = Tags.FindS("URL"); + if (!Parse->FixupURI(URI)) + return _error->Error(_("Malformed stanza %u in source list %s (URI parse)"),i,Fd.Name().c_str()); + string const Dist = Tags.FindS("Dist"); + string const Section = Tags.FindS("Section"); + // check if there are any options we support + const char* option_str[] = { + "arch", "arch+", "arch-", "trusted" }; + for (unsigned int j=0; j < sizeof(option_str)/sizeof(char*); j++) + if (Tags.Exists(option_str[j])) + Options[option_str[j]] = Tags.FindS(option_str[j]); + + // now create one item per section + std::vector list; + if (Section.find(",")) + list = StringSplit(Section, ","); + else + list = StringSplit(Section, " "); + for (std::vector::const_iterator I = list.begin(); + I != list.end(); I++) + Parse->CreateItem(SrcList, URI, Dist, (*I), Options); + + i++; + } + + // we are done + if(i>0) + return true; + + return false; +} + /*}}}*/ // SourceList::FindIndex - Get the index associated with a file /*{{{*/ // --------------------------------------------------------------------- /* */ diff --git a/apt-pkg/sourcelist.h b/apt-pkg/sourcelist.h index af3f4f5c6..5e0d585bb 100644 --- a/apt-pkg/sourcelist.h +++ b/apt-pkg/sourcelist.h @@ -76,8 +76,8 @@ class pkgSourceList std::vector SrcList; - // FIXME: move int Type with the next ABI break - bool ParseFileDeb822(FileFd &Fd); + bool ParseFileDeb822(std::string File); + bool ParseFileOldStyle(std::string File); public: -- cgit v1.2.3 From fce9f472046344d15d4f4df281a003d837cf4177 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 9 Dec 2013 08:30:01 +0100 Subject: add APT::Sources::Use-Deb822 to allow disabling the deb822 parser --- apt-pkg/sourcelist.cc | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 714918bc1..0bbb2bd3f 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -239,7 +239,8 @@ bool pkgSourceList::Read(string File) /* */ bool pkgSourceList::ReadAppend(string File) { - if (ParseFileDeb822(File)) + if (_config->FindB("APT::Sources::Use-Deb822", true) == true) + if (ParseFileDeb822(File)) return true; return ParseFileOldStyle(File); } @@ -305,19 +306,23 @@ bool pkgSourceList::ParseFileOldStyle(string File) /* */ bool pkgSourceList::ParseFileDeb822(string File) { - // FIXME: proper error handling so that we do not error for good old-style - // sources + + pkgTagSection Tags; + map Options; + unsigned int i=0; + + // see if we can read the file + _error->PushToStack(); FileFd Fd(File, FileFd::ReadOnly); + pkgTagFile Sources(&Fd); if (_error->PendingError() == true) { + _error->RevertToStack(); return false; } - - pkgTagSection Tags; - map Options; - unsigned int i=0; + _error->MergeWithStack(); - pkgTagFile Sources(&Fd); + // read step by step while (Sources.Step(Tags) == true) { if(!Tags.Exists("Type")) -- cgit v1.2.3 From 42e19c826b9da6c21a6d286f31db51bc04c73d87 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 9 Dec 2013 08:33:28 +0100 Subject: suppoer $(ARCH) in deb822 sources.list as well --- apt-pkg/sourcelist.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 0bbb2bd3f..99cdbe030 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -327,6 +327,7 @@ bool pkgSourceList::ParseFileDeb822(string File) { if(!Tags.Exists("Type")) continue; + string const type = Tags.FindS("Type"); Type *Parse = Type::GetType(type.c_str()); if (Parse == 0) @@ -335,8 +336,10 @@ bool pkgSourceList::ParseFileDeb822(string File) string URI = Tags.FindS("URL"); if (!Parse->FixupURI(URI)) return _error->Error(_("Malformed stanza %u in source list %s (URI parse)"),i,Fd.Name().c_str()); - string const Dist = Tags.FindS("Dist"); - string const Section = Tags.FindS("Section"); + + string Dist = Tags.FindS("Dist"); + Dist = SubstVar(Dist,"$(ARCH)",_config->Find("APT::Architecture")); + // check if there are any options we support const char* option_str[] = { "arch", "arch+", "arch-", "trusted" }; @@ -345,6 +348,7 @@ bool pkgSourceList::ParseFileDeb822(string File) Options[option_str[j]] = Tags.FindS(option_str[j]); // now create one item per section + string const Section = Tags.FindS("Section"); std::vector list; if (Section.find(",")) list = StringSplit(Section, ","); -- cgit v1.2.3 From c23e6cd58242470daad78ddad85285f9cd7aed0f Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 12 Dec 2013 15:11:01 +0100 Subject: Fix conffile prompt regression (LP: #1260297) This fixes a regression in the conffile prompt for the progress-fd and adds a testcase to ensure this does not regress again. --- apt-pkg/deb/dpkgpm.cc | 10 +++++++--- apt-pkg/install-progress.cc | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index b4bfd1400..0d73733d5 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -44,6 +44,7 @@ #include #include #include +#include #include /*}}}*/ @@ -596,7 +597,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line) errors look like this: 'status: /var/cache/apt/archives/krecipes_0.8.1-0ubuntu1_i386.deb : error : trying to overwrite `/usr/share/doc/kde/HTML/en/krecipes/krectip.png', which is also in package krecipes-data and conffile-prompt like this - 'status: conffile-prompt: conffile : 'current-conffile' 'new-conffile' useredited distedited + 'status:/etc/compiz.conf/compiz.conf : conffile-prompt: 'current-conffile' 'new-conffile' useredited distedited */ if (prefix == "status") { @@ -608,7 +609,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line) WriteApportReport(list[1].c_str(), list[3].c_str()); return; } - else if(action == "conffile") + else if(action == "conffile-prompt") { d->progress->ConffilePrompt(list[1], PackagesDone, PackagesTotal, list[3]); @@ -1036,7 +1037,10 @@ void pkgDPkgPM::StartPtyMagic() if (tcgetattr(STDOUT_FILENO, &d->tt) == 0) { ioctl(1, TIOCGWINSZ, (char *)&win); - if (openpty(&d->master, &d->slave, NULL, &d->tt, &win) < 0) + if (_config->FindB("Dpkg::Use-Pty", true) == false) + { + d->master = d->slave = -1; + } else if (openpty(&d->master, &d->slave, NULL, &d->tt, &win) < 0) { _error->Errno("openpty", _("Can not write log (%s)"), _("Is /dev/pts mounted?")); d->master = d->slave = -1; diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc index b82b7efde..0caf62b61 100644 --- a/apt-pkg/install-progress.cc +++ b/apt-pkg/install-progress.cc @@ -9,7 +9,7 @@ #include #include #include - +#include namespace APT { namespace Progress { -- cgit v1.2.3 From 5e1ed0889d8aac82ca18add8c6139b153225ae71 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 1 Dec 2013 21:52:36 +0100 Subject: query an empty pkgAcqIndexDiffs if index is up-to-date The previous code already did this, this is just being a hell of a lot more obvious, so that it isn't that easy to break in the future. Git-Dch: Ignore --- apt-pkg/acquire-item.cc | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index b76921312..009531c2e 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -426,16 +426,18 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) /*{{{*/ SHA1.AddFD(fd); string const local_sha1 = SHA1.Result(); - if(local_sha1 == ServerSha1) + if(local_sha1 == ServerSha1) { - // we have the same sha1 as the server + // we have the same sha1 as the server so we are done here if(Debug) std::clog << "Package file is up-to-date" << std::endl; - // set found to true, this will queue a pkgAcqIndexDiffs with - // a empty availabe_patches - found = true; - } - else + // list cleanup needs to know that this file as well as the already + // present index is ours, so we create an empty diff to save it for us + new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc, + ExpectedHash, ServerSha1, available_patches); + return true; + } + else { if(Debug) std::clog << "SHA1-Current: " << ServerSha1 << " and we start at "<< fd.Name() << " " << fd.Size() << " " << local_sha1 << std::endl; -- cgit v1.2.3 From 9d39208af5c8c72d3886c70d603921cf427056ee Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 3 Dec 2013 20:53:04 +0100 Subject: allow ':' in GetListOfFilesInDir run-parts doesn't allow this char in valid filenames, but we tend to have files with this character in e.g. /var/lib/apt/lists/ Git-Dch: Ignore --- apt-pkg/contrib/fileutl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 7fbe4d604..130e990c3 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -465,7 +465,7 @@ std::vector GetListOfFilesInDir(string const &Dir, std::vector c const char *C = Ent->d_name; for (; *C != 0; ++C) if (isalpha(*C) == 0 && isdigit(*C) == 0 - && *C != '_' && *C != '-') { + && *C != '_' && *C != '-' && *C != ':') { // no required extension -> dot is a bad character if (*C == '.' && Ext.empty() == false) continue; -- cgit v1.2.3 From 47d2bc78adb49f3182f9a3d7a4baea363e772d64 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 6 Dec 2013 12:17:48 +0100 Subject: implement POC client-side merging of pdiffs via apt-file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The idea of pdiffs is to avoid downloading the hole file by patching the existing index. This works very well, but becomes slow if a lot of patches needs to be applied to reconstruct an up-to-date index and in recent years more and more dinstall (or similar) runs are executed creating more and more pdiffs in the same amount of time, so pdiffs became less useful. The solution is simple: Reduce the amount of patches (which are very small) which need to be applied on top of the index we have available (which is usually pretty big). This can be done in two ways: Either merge the patches on the server-side so that the client has to download only one patch or the patches are all downloaded and merged on the client-side. The first needs a client who is doing one step at a time who can also skip patches if it needs (APT supports this for a long time now). The later is implemented by this commit, but depends on the server NOT merging the patches and the patches being in a strict order in which no patch is skipped. This is traditionally the case for dak, but other repository creators support merging – e.g. reprepro (which helpfully adds a flag indicating that the patches are merged). To support both or even mixes a client needs more information which isn't available for now. This POC uses the external diffindex-rred included in apt-file to do the heavy lifting of merging & applying all patches in one pass, hence to test this feature apt-file needs to be installed. --- apt-pkg/acquire-item.cc | 151 +++++++++++++++++++++++++++++++++++++++++++++++- apt-pkg/acquire-item.h | 100 +++++++++++++++++++++++++++++++- 2 files changed, 247 insertions(+), 4 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 009531c2e..b5b9577ef 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -498,14 +498,42 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) /*{{{*/ } // we have something, queue the next diff - if(found) + if(found) { // queue the diffs string::size_type const last_space = Description.rfind(" "); if(last_space != string::npos) Description.erase(last_space, Description.size()-last_space); - new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc, - ExpectedHash, ServerSha1, available_patches); + + /* decide if we should download patches one by one or in one go: + The first is good if the server merges patches, but many don't so client + based merging can be attempt in which case the second is better. + "bad things" will happen if patches are merged on the server, + but client side merging is attempt as well */ + bool pdiff_merge = _config->FindB("Acquire::PDiffs::Merge", true); + if (pdiff_merge == true) + { + // this perl script is provided by apt-file + pdiff_merge = FileExists(_config->FindFile("Dir::Bin::rred", "/usr/bin/diffindex-rred")); + if (pdiff_merge == true) + { + // reprepro adds this flag if it has merged patches on the server + std::string const precedence = Tags.FindS("X-Patch-Precedence"); + pdiff_merge = (precedence != "merged"); + } + } + + if (pdiff_merge == false) + new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc, + ExpectedHash, ServerSha1, available_patches); + else + { + std::vector *diffs = new std::vector(available_patches.size()); + for(size_t i = 0; i < available_patches.size(); ++i) + (*diffs)[i] = new pkgAcqIndexMergeDiffs(Owner, RealURI, Description, Desc.ShortDesc, ExpectedHash, + available_patches[i], diffs); + } + Complete = false; Status = StatDone; Dequeue(); @@ -754,6 +782,123 @@ void pkgAcqIndexDiffs::Done(string Message,unsigned long long Size,string Md5Has } } /*}}}*/ +// AcqIndexMergeDiffs::AcqIndexMergeDiffs - Constructor /*{{{*/ +pkgAcqIndexMergeDiffs::pkgAcqIndexMergeDiffs(pkgAcquire *Owner, + string const &URI, string const &URIDesc, + string const &ShortDesc, HashString const &ExpectedHash, + DiffInfo const &patch, + std::vector const * const allPatches) + : Item(Owner), RealURI(URI), ExpectedHash(ExpectedHash), + patch(patch),allPatches(allPatches), State(StateFetchDiff) +{ + + DestFile = _config->FindDir("Dir::State::lists") + "partial/"; + DestFile += URItoFileName(URI); + + Debug = _config->FindB("Debug::pkgAcquire::Diffs",false); + + Description = URIDesc; + Desc.Owner = this; + Desc.ShortDesc = ShortDesc; + + Desc.URI = string(RealURI) + ".diff/" + patch.file + ".gz"; + Desc.Description = Description + " " + patch.file + string(".pdiff"); + DestFile = _config->FindDir("Dir::State::lists") + "partial/"; + DestFile += URItoFileName(RealURI + ".diff/" + patch.file); + + if(Debug) + std::clog << "pkgAcqIndexMergeDiffs: " << Desc.URI << std::endl; + + QueueURI(Desc); +} + /*}}}*/ +void pkgAcqIndexMergeDiffs::Failed(string Message,pkgAcquire::MethodConfig *Cnf)/*{{{*/ +{ + if(Debug) + std::clog << "pkgAcqIndexMergeDiffs failed: " << Desc.URI << " with " << Message << std::endl; + Complete = false; + Status = StatDone; + Dequeue(); + + // check if we are the first to fail, otherwise we are done here + State = StateDoneDiff; + for (std::vector::const_iterator I = allPatches->begin(); + I != allPatches->end(); ++I) + if ((*I)->State == StateErrorDiff) + return; + + // first failure means we should fallback + State = StateErrorDiff; + std::clog << "Falling back to normal index file aquire" << std::endl; + new pkgAcqIndex(Owner, RealURI, Description,Desc.ShortDesc, + ExpectedHash); +} + /*}}}*/ +void pkgAcqIndexMergeDiffs::Done(string Message,unsigned long long Size,string Md5Hash, /*{{{*/ + pkgAcquire::MethodConfig *Cnf) +{ + if(Debug) + std::clog << "pkgAcqIndexMergeDiffs::Done(): " << Desc.URI << std::endl; + + Item::Done(Message,Size,Md5Hash,Cnf); + + string const FinalFile = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI); + + if (State == StateFetchDiff) + { + // rred expects the patch as $FinalFile.ed.$patchname.gz + Rename(DestFile, FinalFile + ".ed." + patch.file + ".gz"); + + // check if this is the last completed diff + State = StateDoneDiff; + for (std::vector::const_iterator I = allPatches->begin(); + I != allPatches->end(); ++I) + if ((*I)->State != StateDoneDiff) + { + if(Debug) + std::clog << "Not the last done diff in the batch: " << Desc.URI << std::endl; + return; + } + + // this is the last completed diff, so we are ready to apply now + State = StateApplyDiff; + + if(Debug) + std::clog << "Sending to rred method: " << FinalFile << std::endl; + + Local = true; + Desc.URI = "rred:" + FinalFile; + QueueURI(Desc); + Mode = "rred"; + return; + } + // success in download/apply all diffs, clean up + else if (State == StateApplyDiff) + { + // see if we really got the expected file + if(!ExpectedHash.empty() && !ExpectedHash.VerifyFile(DestFile)) + { + RenameOnError(HashSumMismatch); + return; + } + + // move the result into place + if(Debug) + std::clog << "Moving patched file in place: " << std::endl + << DestFile << " -> " << FinalFile << std::endl; + Rename(DestFile, FinalFile); + chmod(FinalFile.c_str(), 0644); + + // otherwise lists cleanup will eat the file + DestFile = FinalFile; + + // all set and done + Complete = true; + if(Debug) + std::clog << "allDone: " << DestFile << "\n" << std::endl; + } +} + /*}}}*/ // AcqIndex::AcqIndex - Constructor /*{{{*/ // --------------------------------------------------------------------- /* The package file is added to the queue and a second class is diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h index 6b4f73708..5a1c7979c 100644 --- a/apt-pkg/acquire-item.h +++ b/apt-pkg/acquire-item.h @@ -429,7 +429,105 @@ class pkgAcqDiffIndex : public pkgAcquire::Item std::string ShortDesc, HashString ExpectedHash); }; /*}}}*/ -/** \brief An item that is responsible for fetching all the patches {{{ +/** \brief An item that is responsible for fetching client-merge patches {{{ + * that need to be applied to a given package index file. + * + * Instead of downloading and applying each patch one by one like its + * sister #pkgAcqIndexDiffs this class will download all patches at once + * and call rred with all the patches downloaded once. Rred will then + * merge and apply them in one go, which should be a lot faster – but is + * incompatible with server-based merges of patches like reprepro can do. + * + * \sa pkgAcqDiffIndex, pkgAcqIndex + */ +class pkgAcqIndexMergeDiffs : public pkgAcquire::Item +{ + protected: + + /** \brief If \b true, debugging output will be written to + * std::clog. + */ + bool Debug; + + /** \brief description of the item that is currently being + * downloaded. + */ + pkgAcquire::ItemDesc Desc; + + /** \brief URI of the package index file that is being + * reconstructed. + */ + std::string RealURI; + + /** \brief HashSum of the package index file that is being + * reconstructed. + */ + HashString ExpectedHash; + + /** \brief description of the file being downloaded. */ + std::string Description; + + /** \brief information about the current patch */ + struct DiffInfo const patch; + + /** \brief list of all download items for the patches */ + std::vector const * const allPatches; + + /** The current status of this patch. */ + enum DiffState + { + /** \brief The diff is currently being fetched. */ + StateFetchDiff, + + /** \brief The diff is currently being applied. */ + StateApplyDiff, + + /** \brief the work with this diff is done */ + StateDoneDiff, + + /** \brief something bad happened and fallback was triggered */ + StateErrorDiff + } State; + + public: + /** \brief Called when the patch file failed to be downloaded. + * + * This method will fall back to downloading the whole index file + * outright; its arguments are ignored. + */ + virtual void Failed(std::string Message,pkgAcquire::MethodConfig *Cnf); + + virtual void Done(std::string Message,unsigned long long Size,std::string Md5Hash, + pkgAcquire::MethodConfig *Cnf); + virtual std::string DescURI() {return RealURI + "Index";}; + + /** \brief Create an index merge-diff item. + * + * \param Owner The pkgAcquire object that owns this item. + * + * \param URI The URI of the package index file being + * reconstructed. + * + * \param URIDesc A long description of this item. + * + * \param ShortDesc A brief description of this item. + * + * \param ExpectedHash The expected md5sum of the completely + * reconstructed package index file; the index file will be tested + * against this value when it is entirely reconstructed. + * + * \param patch contains infos about the patch this item is supposed + * to download which were read from the index + * + * \param allPatches contains all related items so that each item can + * check if it was the last one to complete the download step + */ + pkgAcqIndexMergeDiffs(pkgAcquire *Owner,std::string const &URI,std::string const &URIDesc, + std::string const &ShortDesc, HashString const &ExpectedHash, + DiffInfo const &patch, std::vector const * const allPatches); +}; + /*}}}*/ +/** \brief An item that is responsible for fetching server-merge patches {{{ * that need to be applied to a given package index file. * * After downloading and applying a single patch, this item will -- cgit v1.2.3 From 75ab11ae3880530c5354cc90c8d1ff0998f8146b Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 21 Dec 2013 18:50:03 +0100 Subject: make /etc/apt/preferences parser deal with comment only sections --- apt-pkg/policy.cc | 4 ++++ apt-pkg/tagfile.cc | 11 +++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc index 0a06cc6e3..d0f97441d 100644 --- a/apt-pkg/policy.cc +++ b/apt-pkg/policy.cc @@ -405,6 +405,10 @@ bool ReadPinFile(pkgPolicy &Plcy,string File) PreferenceSection Tags; while (TF.Step(Tags) == true) { + // can happen when there are only comments in a record + if (Tags.Count() == 0) + continue; + string Name = Tags.FindS("Package"); if (Name.empty() == true) return _error->Error(_("Invalid record in the preferences file %s, no Package header"), File.c_str()); diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc index e0802e3d5..bef3c76ba 100644 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@ -259,7 +259,12 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength) TagCount = 0; while (TagCount+1 < sizeof(Indexes)/sizeof(Indexes[0]) && Stop < End) { - TrimRecord(true,End); + TrimRecord(true,End); + + // this can happen when TrimRecord trims away the entire Record + // (e.g. because it just contains comments) + if(Stop == End) + return true; // Start a new index and add it to the hash if (isspace(Stop[0]) == 0) @@ -273,7 +278,9 @@ bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength) if (Stop == 0) return false; - for (; Stop+1 < End && Stop[1] == '\r'; Stop++); + for (; Stop+1 < End && Stop[1] == '\r'; Stop++) + /* nothing */ + ; // Double newline marks the end of the record if (Stop+1 < End && Stop[1] == '\n') -- cgit v1.2.3 From e5e51967a479552f6513d585a6eeefba05c7a12f Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sun, 22 Dec 2013 14:38:39 +0100 Subject: first proof-of-concept for a fix for #731738 --- apt-pkg/deb/dpkgpm.cc | 2 +- apt-pkg/install-progress.cc | 9 ++++++++- apt-pkg/install-progress.h | 4 ++-- 3 files changed, 11 insertions(+), 4 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index b4bfd1400..b9f839e82 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1182,7 +1182,7 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress) StartPtyMagic(); // Tell the progress that its starting and fork dpkg - d->progress->Start(); + d->progress->Start(d->master); // this loop is runs once per dpkg operation vector::const_iterator I = List.begin(); diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc index b82b7efde..2215fb1f5 100644 --- a/apt-pkg/install-progress.cc +++ b/apt-pkg/install-progress.cc @@ -273,11 +273,18 @@ void PackageManagerFancy::HandleSIGWINCH(int) SetupTerminalScrollArea(nr_terminal_rows); } -void PackageManagerFancy::Start() +void PackageManagerFancy::Start(int child_pty) { int nr_terminal_rows = GetNumberTerminalRows(); if (nr_terminal_rows > 0) + { SetupTerminalScrollArea(nr_terminal_rows); + // *cough* + struct winsize win; + ioctl(child_pty, TIOCGWINSZ, (char *)&win); + win.ws_row = nr_terminal_rows - 1; + ioctl(child_pty, TIOCSWINSZ, (char *)&win); + } } void PackageManagerFancy::Stop() diff --git a/apt-pkg/install-progress.h b/apt-pkg/install-progress.h index 4b7590983..010be82fd 100644 --- a/apt-pkg/install-progress.h +++ b/apt-pkg/install-progress.h @@ -28,7 +28,7 @@ namespace Progress { virtual ~PackageManager() {}; /* Global Start/Stop */ - virtual void Start() {}; + virtual void Start(int child_pty=-1) {}; virtual void Stop() {}; /* When dpkg is invoked (may happen multiple times for each @@ -125,7 +125,7 @@ namespace Progress { public: PackageManagerFancy(); ~PackageManagerFancy(); - virtual void Start(); + virtual void Start(int child_pty=-1); virtual void Stop(); virtual bool StatusChanged(std::string PackageName, unsigned int StepsDone, -- cgit v1.2.3 From 4754718a4461ebff89f5b49c385a007b4197bcff Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sun, 22 Dec 2013 14:38:39 +0100 Subject: first proof-of-concept for a fix for #731738 --- apt-pkg/deb/dpkgpm.cc | 2 +- apt-pkg/install-progress.cc | 9 ++++++++- apt-pkg/install-progress.h | 4 ++-- 3 files changed, 11 insertions(+), 4 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index b4bfd1400..b9f839e82 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1182,7 +1182,7 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress) StartPtyMagic(); // Tell the progress that its starting and fork dpkg - d->progress->Start(); + d->progress->Start(d->master); // this loop is runs once per dpkg operation vector::const_iterator I = List.begin(); diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc index b82b7efde..2215fb1f5 100644 --- a/apt-pkg/install-progress.cc +++ b/apt-pkg/install-progress.cc @@ -273,11 +273,18 @@ void PackageManagerFancy::HandleSIGWINCH(int) SetupTerminalScrollArea(nr_terminal_rows); } -void PackageManagerFancy::Start() +void PackageManagerFancy::Start(int child_pty) { int nr_terminal_rows = GetNumberTerminalRows(); if (nr_terminal_rows > 0) + { SetupTerminalScrollArea(nr_terminal_rows); + // *cough* + struct winsize win; + ioctl(child_pty, TIOCGWINSZ, (char *)&win); + win.ws_row = nr_terminal_rows - 1; + ioctl(child_pty, TIOCSWINSZ, (char *)&win); + } } void PackageManagerFancy::Stop() diff --git a/apt-pkg/install-progress.h b/apt-pkg/install-progress.h index 4b7590983..010be82fd 100644 --- a/apt-pkg/install-progress.h +++ b/apt-pkg/install-progress.h @@ -28,7 +28,7 @@ namespace Progress { virtual ~PackageManager() {}; /* Global Start/Stop */ - virtual void Start() {}; + virtual void Start(int child_pty=-1) {}; virtual void Stop() {}; /* When dpkg is invoked (may happen multiple times for each @@ -125,7 +125,7 @@ namespace Progress { public: PackageManagerFancy(); ~PackageManagerFancy(); - virtual void Start(); + virtual void Start(int child_pty=-1); virtual void Stop(); virtual bool StatusChanged(std::string PackageName, unsigned int StepsDone, -- cgit v1.2.3 From 38beb8b5936e9d85a5bb99bf3860f082bbe34439 Mon Sep 17 00:00:00 2001 From: Thomas Bechtold Date: Sun, 22 Dec 2013 11:40:49 +0100 Subject: apt-pkg/contrib/gpgv.cc: use /tmp as fallback dir if the directory given by $TMPDIR is not available, use /tmp as fallback. --- apt-pkg/contrib/gpgv.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/gpgv.cc b/apt-pkg/contrib/gpgv.cc index f47e7ea48..8f619fee2 100644 --- a/apt-pkg/contrib/gpgv.cc +++ b/apt-pkg/contrib/gpgv.cc @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -22,11 +23,15 @@ static char * GenerateTemporaryFileTemplate(const char *basename) /*{{{*/ { const char *tmpdir = getenv("TMPDIR"); + #ifdef P_tmpdir if (!tmpdir) tmpdir = P_tmpdir; #endif - if (!tmpdir) + + // check that tmpdir is set and exists + struct stat st; + if (!tmpdir || stat(tmpdir, &st) != 0) tmpdir = "/tmp"; std::string out; -- cgit v1.2.3 From 68e0172140872d8044b3c768a6bea3ac58d426c4 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sun, 22 Dec 2013 22:15:52 +0100 Subject: factor GetTempDir out --- apt-pkg/contrib/fileutl.cc | 17 +++++++++++++++++ apt-pkg/contrib/fileutl.h | 2 ++ apt-pkg/contrib/gpgv.cc | 15 ++------------- 3 files changed, 21 insertions(+), 13 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 7fbe4d604..847d8b47f 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -1827,3 +1827,20 @@ std::vector Glob(std::string const &pattern, int flags) return result; } /*}}}*/ + +std::string GetTempDir() +{ + const char *tmpdir = getenv("TMPDIR"); + +#ifdef P_tmpdir + if (!tmpdir) + tmpdir = P_tmpdir; +#endif + + // check that tmpdir is set and exists + struct stat st; + if (!tmpdir || stat(tmpdir, &st) != 0) + tmpdir = "/tmp"; + + return string(tmpdir); +} diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index e9a9aab28..e752e9621 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -165,6 +165,8 @@ bool DirectoryExists(std::string const &Path) __attrib_const; bool CreateDirectory(std::string const &Parent, std::string const &Path); time_t GetModificationTime(std::string const &Path); +std::string GetTempDir(); + /** \brief Ensure the existence of the given Path * * \param Parent directory of the Path directory - a trailing diff --git a/apt-pkg/contrib/gpgv.cc b/apt-pkg/contrib/gpgv.cc index 8f619fee2..f57a72d86 100644 --- a/apt-pkg/contrib/gpgv.cc +++ b/apt-pkg/contrib/gpgv.cc @@ -22,20 +22,9 @@ /*}}}*/ static char * GenerateTemporaryFileTemplate(const char *basename) /*{{{*/ { - const char *tmpdir = getenv("TMPDIR"); - -#ifdef P_tmpdir - if (!tmpdir) - tmpdir = P_tmpdir; -#endif - - // check that tmpdir is set and exists - struct stat st; - if (!tmpdir || stat(tmpdir, &st) != 0) - tmpdir = "/tmp"; - std::string out; - strprintf(out, "%s/%s.XXXXXX", tmpdir, basename); + std::string tmpdir = GetTempDir(); + strprintf(out, "%s/%s.XXXXXX", tmpdir.c_str(), basename); return strdup(out.c_str()); } /*}}}*/ -- cgit v1.2.3 From a077861ad0f2e643307c2380a060a3b11914aa34 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 23 Dec 2013 13:35:08 +0100 Subject: add basic tests for GetTempDir() --- apt-pkg/contrib/fileutl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 847d8b47f..efbf7aaf4 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -1839,7 +1839,7 @@ std::string GetTempDir() // check that tmpdir is set and exists struct stat st; - if (!tmpdir || stat(tmpdir, &st) != 0) + if (!tmpdir || strlen(tmpdir) == 0 || stat(tmpdir, &st) != 0) tmpdir = "/tmp"; return string(tmpdir); -- cgit v1.2.3 From 5ed887855df9c39dcd22971073ed05b28a9ee95f Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 28 Dec 2013 00:26:17 +0100 Subject: properly handle SIGWINCH in PackageManagerFancy again --- apt-pkg/install-progress.cc | 65 +++++++++++++++++++++++++++++---------------- apt-pkg/install-progress.h | 12 ++++++--- 2 files changed, 51 insertions(+), 26 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc index 2215fb1f5..bfc00bd06 100644 --- a/apt-pkg/install-progress.cc +++ b/apt-pkg/install-progress.cc @@ -9,7 +9,7 @@ #include #include #include - +#include namespace APT { namespace Progress { @@ -222,17 +222,47 @@ bool PackageManagerProgressDeb822Fd::StatusChanged(std::string PackageName, return true; } + +PackageManagerFancy::PackageManagerFancy() + : child_pty(-1) +{ + // setup terminal size + old_SIGWINCH = signal(SIGWINCH, PackageManagerFancy::staticSIGWINCH); + instances.push_back(this); +} +std::vector PackageManagerFancy::instances; + +PackageManagerFancy::~PackageManagerFancy() +{ + instances.erase(find(instances.begin(), instances.end(), this)); + signal(SIGWINCH, old_SIGWINCH); +} + +void PackageManagerFancy::staticSIGWINCH(int signum) +{ + std::vector::const_iterator I; + for(I = instances.begin(); I != instances.end(); I++) + (*I)->HandleSIGWINCH(signum); +} + int PackageManagerFancy::GetNumberTerminalRows() { struct winsize win; + // FIXME: get from "child_pty" instead? if(ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&win) != 0) return -1; + + if(_config->FindB("Debug::InstallProgress::Fancy", false) == true) + std::cerr << "GetNumberTerminalRows: " << win.ws_row << std::endl; return win.ws_row; } void PackageManagerFancy::SetupTerminalScrollArea(int nr_rows) { + if(_config->FindB("Debug::InstallProgress::Fancy", false) == true) + std::cerr << "SetupTerminalScrollArea: " << nr_rows << std::endl; + // scroll down a bit to avoid visual glitch when the screen // area shrinks by one row std::cout << "\n"; @@ -241,30 +271,22 @@ void PackageManagerFancy::SetupTerminalScrollArea(int nr_rows) std::cout << "\033[s"; // set scroll region (this will place the cursor in the top left) - std::cout << "\033[1;" << nr_rows - 1 << "r"; + std::cout << "\033[0;" << nr_rows - 1 << "r"; // restore cursor but ensure its inside the scrolling area std::cout << "\033[u"; static const char *move_cursor_up = "\033[1A"; std::cout << move_cursor_up; - // setup env for (hopefully!) ncurses - string s; - strprintf(s, "%i", nr_rows); - setenv("LINES", s.c_str(), 1); - + // ensure its flushed std::flush(std::cout); -} -PackageManagerFancy::PackageManagerFancy() -{ - // setup terminal size - old_SIGWINCH = signal(SIGWINCH, HandleSIGWINCH); -} - -PackageManagerFancy::~PackageManagerFancy() -{ - signal(SIGWINCH, old_SIGWINCH); + // setup tty size to ensure xterm/linux console are working properly too + // see bug #731738 + struct winsize win; + ioctl(child_pty, TIOCGWINSZ, (char *)&win); + win.ws_row = nr_rows - 1; + ioctl(child_pty, TIOCSWINSZ, (char *)&win); } void PackageManagerFancy::HandleSIGWINCH(int) @@ -273,17 +295,13 @@ void PackageManagerFancy::HandleSIGWINCH(int) SetupTerminalScrollArea(nr_terminal_rows); } -void PackageManagerFancy::Start(int child_pty) +void PackageManagerFancy::Start(int a_child_pty) { + child_pty = a_child_pty; int nr_terminal_rows = GetNumberTerminalRows(); if (nr_terminal_rows > 0) { SetupTerminalScrollArea(nr_terminal_rows); - // *cough* - struct winsize win; - ioctl(child_pty, TIOCGWINSZ, (char *)&win); - win.ws_row = nr_terminal_rows - 1; - ioctl(child_pty, TIOCSWINSZ, (char *)&win); } } @@ -298,6 +316,7 @@ void PackageManagerFancy::Stop() static const char* clear_screen_below_cursor = "\033[J"; std::cout << clear_screen_below_cursor; } + child_pty = -1; } bool PackageManagerFancy::StatusChanged(std::string PackageName, diff --git a/apt-pkg/install-progress.h b/apt-pkg/install-progress.h index 010be82fd..513de1c08 100644 --- a/apt-pkg/install-progress.h +++ b/apt-pkg/install-progress.h @@ -116,11 +116,17 @@ namespace Progress { class PackageManagerFancy : public PackageManager { + private: + static void staticSIGWINCH(int); + static std::vector instances; + protected: - static void SetupTerminalScrollArea(int nr_rows); - static int GetNumberTerminalRows(); - static void HandleSIGWINCH(int); + void SetupTerminalScrollArea(int nr_rows); + void HandleSIGWINCH(int); + + int GetNumberTerminalRows(); sighandler_t old_SIGWINCH; + int child_pty; public: PackageManagerFancy(); -- cgit v1.2.3 From 23bd09778261c945b460b46d855b1a6ef998cfd8 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 28 Dec 2013 09:50:06 +0100 Subject: add missing vector include --- apt-pkg/install-progress.h | 1 + 1 file changed, 1 insertion(+) (limited to 'apt-pkg') diff --git a/apt-pkg/install-progress.h b/apt-pkg/install-progress.h index 513de1c08..8a5b68a8f 100644 --- a/apt-pkg/install-progress.h +++ b/apt-pkg/install-progress.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace APT { namespace Progress { -- cgit v1.2.3 From d2d68aaf5bc2211e9c488f2603ccb4e5fd591a6d Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 4 Jan 2014 15:39:04 +0100 Subject: improve tests --- apt-pkg/sourcelist.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 99cdbe030..35e13b6f5 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -342,7 +342,8 @@ bool pkgSourceList::ParseFileDeb822(string File) // check if there are any options we support const char* option_str[] = { - "arch", "arch+", "arch-", "trusted" }; + "arch", "arch+", "arch-", "trusted", + }; for (unsigned int j=0; j < sizeof(option_str)/sizeof(char*); j++) if (Tags.Exists(option_str[j])) Options[option_str[j]] = Tags.FindS(option_str[j]); -- cgit v1.2.3 From 4194c9aee2766845618ef0431fd4803b0467aab7 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 4 Jan 2014 16:23:32 +0100 Subject: improve error message --- apt-pkg/sourcelist.cc | 34 ++++++++++++++++++++++------------ apt-pkg/sourcelist.h | 2 +- 2 files changed, 23 insertions(+), 13 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 35e13b6f5..5e4a58e95 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -240,8 +240,14 @@ bool pkgSourceList::Read(string File) bool pkgSourceList::ReadAppend(string File) { if (_config->FindB("APT::Sources::Use-Deb822", true) == true) - if (ParseFileDeb822(File)) + { + int lines_parsed =ParseFileDeb822(File); + if (lines_parsed < 0) + return false; + else if (lines_parsed > 0) return true; + // no lines parsed ... fall through and use old style parser + } return ParseFileOldStyle(File); } @@ -303,10 +309,9 @@ bool pkgSourceList::ParseFileOldStyle(string File) /*}}}*/ // SourceList::ParseFileDeb822 - Parse deb822 style sources.list /*{{{*/ // --------------------------------------------------------------------- -/* */ -bool pkgSourceList::ParseFileDeb822(string File) +/* Returns: the number of stanzas parsed*/ +int pkgSourceList::ParseFileDeb822(string File) { - pkgTagSection Tags; map Options; unsigned int i=0; @@ -318,7 +323,7 @@ bool pkgSourceList::ParseFileDeb822(string File) if (_error->PendingError() == true) { _error->RevertToStack(); - return false; + return 0; } _error->MergeWithStack(); @@ -331,11 +336,19 @@ bool pkgSourceList::ParseFileDeb822(string File) string const type = Tags.FindS("Type"); Type *Parse = Type::GetType(type.c_str()); if (Parse == 0) - return _error->Error(_("Type '%s' is not known on stanza %u in source list %s"),type.c_str(),i,Fd.Name().c_str()); + { + _error->Error(_("Type '%s' is not known on stanza %u in source list %s"),type.c_str(),i,Fd.Name().c_str()); + // true means we do not retry with old-style sources.list + return -1; + } string URI = Tags.FindS("URL"); if (!Parse->FixupURI(URI)) - return _error->Error(_("Malformed stanza %u in source list %s (URI parse)"),i,Fd.Name().c_str()); + { + _error->Error(_("Malformed stanza %u in source list %s (URI parse)"),i,Fd.Name().c_str()); + // means we do not retry with old-style sources.list + return -1; + } string Dist = Tags.FindS("Dist"); Dist = SubstVar(Dist,"$(ARCH)",_config->Find("APT::Architecture")); @@ -362,11 +375,8 @@ bool pkgSourceList::ParseFileDeb822(string File) i++; } - // we are done - if(i>0) - return true; - - return false; + // we are done, return the number of stanzas read + return i; } /*}}}*/ // SourceList::FindIndex - Get the index associated with a file /*{{{*/ diff --git a/apt-pkg/sourcelist.h b/apt-pkg/sourcelist.h index 5e0d585bb..d83c76d6a 100644 --- a/apt-pkg/sourcelist.h +++ b/apt-pkg/sourcelist.h @@ -76,7 +76,7 @@ class pkgSourceList std::vector SrcList; - bool ParseFileDeb822(std::string File); + int ParseFileDeb822(std::string File); bool ParseFileOldStyle(std::string File); public: -- cgit v1.2.3 From 1e4a2b763f2225d6de3d498263da2a1a12697667 Mon Sep 17 00:00:00 2001 From: Anthony Towns Date: Wed, 15 Jan 2014 15:55:26 +0100 Subject: correct IndexDiff vs DiffIndex in Debug output --- apt-pkg/acquire-item.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index b5b9577ef..73f5f4901 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -369,10 +369,10 @@ pkgAcqDiffIndex::pkgAcqDiffIndex(pkgAcquire *Owner, return; } - if(Debug) - std::clog << "pkgAcqIndexDiffs::pkgAcqIndexDiffs(): " - << CurrentPackagesFile << std::endl; - + if(Debug) + std::clog << "pkgAcqDiffIndex::pkgAcqDiffIndex(): " + << CurrentPackagesFile << std::endl; + QueueURI(Desc); } @@ -398,8 +398,8 @@ string pkgAcqDiffIndex::Custom600Headers() bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) /*{{{*/ { if(Debug) - std::clog << "pkgAcqIndexDiffs::ParseIndexDiff() " << IndexDiffFile - << std::endl; + std::clog << "pkgAcqDiffIndex::ParseIndexDiff() " << IndexDiffFile + << std::endl; pkgTagSection Tags; string ServerSha1; -- cgit v1.2.3 From c3a17127ad383ec8e1f480ff2e1a4dccaa537a11 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 27 Dec 2013 14:52:15 +0100 Subject: reenable unlimited pdiff files download In 51fc6def77edfb1f429a48e5169519e9e05a759b we limited the amount of pdiff to be downloaded per index to 20. This was a compromise between not letting it go overboard (becoming even slower) and not using bandwidth needlessly. Now that with the POC the speed reason is gone it makes sense again to download as much files as we possible can via pdiff to save bandwidth (and possibly even time). It also avoids problems with the limit in cases we were we deal with a server merged archieve as this limit assumes a strict patch progression. --- apt-pkg/acquire-item.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 73f5f4901..7f6443555 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -462,7 +462,7 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) /*{{{*/ if (available_patches.empty() == false) { // patching with too many files is rather slow compared to a fast download - unsigned long const fileLimit = _config->FindI("Acquire::PDiffs::FileLimit", 20); + unsigned long const fileLimit = _config->FindI("Acquire::PDiffs::FileLimit", 0); if (fileLimit != 0 && fileLimit < available_patches.size()) { if (Debug) -- cgit v1.2.3 From 50bd6fd3794dd1f61185302129dc6cd218d20b98 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 15 Jan 2014 17:23:05 +0100 Subject: integrate Anthonys rred with POC for client-side merge Providing the benefits of both without the downsides :) (ABI breaks or external dependencies) For this Anthonys rred is equipped with: - magic-filename-pickup of patches rather than explicit messages - use of FileFd instead of FILE* to get on-the-fly uncompress of the gzip compressed pdiff patches The acquire code in turn stops checking for apt-file's helper as our own rred is now clever enough for our needs. --- apt-pkg/acquire-item.cc | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 7f6443555..1185908f3 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -513,14 +513,9 @@ bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) /*{{{*/ bool pdiff_merge = _config->FindB("Acquire::PDiffs::Merge", true); if (pdiff_merge == true) { - // this perl script is provided by apt-file - pdiff_merge = FileExists(_config->FindFile("Dir::Bin::rred", "/usr/bin/diffindex-rred")); - if (pdiff_merge == true) - { - // reprepro adds this flag if it has merged patches on the server - std::string const precedence = Tags.FindS("X-Patch-Precedence"); - pdiff_merge = (precedence != "merged"); - } + // reprepro adds this flag if it has merged patches on the server + std::string const precedence = Tags.FindS("X-Patch-Precedence"); + pdiff_merge = (precedence != "merged"); } if (pdiff_merge == false) -- cgit v1.2.3 From db6594dfc508378b6d658aff2761da5406404238 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 16 Jan 2014 08:03:24 +0100 Subject: remove "," in components again --- apt-pkg/sourcelist.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 5e4a58e95..42ada7e18 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -363,11 +363,7 @@ int pkgSourceList::ParseFileDeb822(string File) // now create one item per section string const Section = Tags.FindS("Section"); - std::vector list; - if (Section.find(",")) - list = StringSplit(Section, ","); - else - list = StringSplit(Section, " "); + std::vector list = StringSplit(Section, " "); for (std::vector::const_iterator I = list.begin(); I != list.end(); I++) Parse->CreateItem(SrcList, URI, Dist, (*I), Options); -- cgit v1.2.3 From 7037aab52fc935298b033a4c7ba7ccb5b697622e Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 16 Jan 2014 16:25:33 +0100 Subject: * refactor to have a new virtual ParseStanza Have a similar ParseStanza() to the current ParseLine(). Rename the Architectures options in deb822 to make it more user friendly --- apt-pkg/sourcelist.cc | 65 ++++++++++++++++++++++++++++++--------------------- apt-pkg/sourcelist.h | 5 ++++ 2 files changed, 44 insertions(+), 26 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 42ada7e18..fe0eace07 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -71,6 +71,44 @@ bool pkgSourceList::Type::FixupURI(string &URI) const return true; } /*}}}*/ +bool pkgSourceList::Type::ParseStanza(vector &List, + pkgTagSection &Tags, + int i, + FileFd &Fd) +{ + map Options; + + string URI = Tags.FindS("URL"); + if (!FixupURI(URI)) + { + _error->Error(_("Malformed stanza %u in source list %s (URI parse)"),i,Fd.Name().c_str()); + return false; + } + + string Dist = Tags.FindS("Dist"); + Dist = SubstVar(Dist,"$(ARCH)",_config->Find("APT::Architecture")); + + // Define external/internal options + const char* option_deb822[] = { + "Architectures", "Architectures-Add", "Architectures-Delete", "Trusted", + }; + const char* option_internal[] = { + "arch", "arch+", "arch-", "trusted", + }; + for (unsigned int j=0; j < sizeof(option_deb822)/sizeof(char*); j++) + if (Tags.Exists(option_deb822[j])) + Options[option_internal[j]] = Tags.FindS(option_deb822[j]); + + // now create one item per section + string const Section = Tags.FindS("Section"); + std::vector list = StringSplit(Section, " "); + for (std::vector::const_iterator I = list.begin(); + I != list.end(); I++) + return CreateItem(List, URI, Dist, (*I), Options); + + return true; +} + // Type::ParseLine - Parse a single line /*{{{*/ // --------------------------------------------------------------------- /* This is a generic one that is the 'usual' format for sources.list @@ -313,7 +351,6 @@ bool pkgSourceList::ParseFileOldStyle(string File) int pkgSourceList::ParseFileDeb822(string File) { pkgTagSection Tags; - map Options; unsigned int i=0; // see if we can read the file @@ -338,35 +375,11 @@ int pkgSourceList::ParseFileDeb822(string File) if (Parse == 0) { _error->Error(_("Type '%s' is not known on stanza %u in source list %s"),type.c_str(),i,Fd.Name().c_str()); - // true means we do not retry with old-style sources.list return -1; } - string URI = Tags.FindS("URL"); - if (!Parse->FixupURI(URI)) - { - _error->Error(_("Malformed stanza %u in source list %s (URI parse)"),i,Fd.Name().c_str()); - // means we do not retry with old-style sources.list + if (!Parse->ParseStanza(SrcList, Tags, i, Fd)) return -1; - } - - string Dist = Tags.FindS("Dist"); - Dist = SubstVar(Dist,"$(ARCH)",_config->Find("APT::Architecture")); - - // check if there are any options we support - const char* option_str[] = { - "arch", "arch+", "arch-", "trusted", - }; - for (unsigned int j=0; j < sizeof(option_str)/sizeof(char*); j++) - if (Tags.Exists(option_str[j])) - Options[option_str[j]] = Tags.FindS(option_str[j]); - - // now create one item per section - string const Section = Tags.FindS("Section"); - std::vector list = StringSplit(Section, " "); - for (std::vector::const_iterator I = list.begin(); - I != list.end(); I++) - Parse->CreateItem(SrcList, URI, Dist, (*I), Options); i++; } diff --git a/apt-pkg/sourcelist.h b/apt-pkg/sourcelist.h index d83c76d6a..0ccb4aa00 100644 --- a/apt-pkg/sourcelist.h +++ b/apt-pkg/sourcelist.h @@ -31,6 +31,7 @@ #include #include #include +#include #ifndef APT_8_CLEANER_HEADERS #include @@ -60,6 +61,10 @@ class pkgSourceList const char *Label; bool FixupURI(std::string &URI) const; + virtual bool ParseStanza(std::vector &List, + pkgTagSection &Tags, + int stanza_n, + FileFd &Fd); virtual bool ParseLine(std::vector &List, const char *Buffer, unsigned long const &CurLine,std::string const &File) const; -- cgit v1.2.3 From 796a0eff1acebe858632c344e77bfc3189b2244f Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 16 Jan 2014 17:00:56 +0100 Subject: rename "distribution" in sources.list to "suite" --- apt-pkg/sourcelist.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index fe0eace07..ddebd206d 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -85,7 +85,7 @@ bool pkgSourceList::Type::ParseStanza(vector &List, return false; } - string Dist = Tags.FindS("Dist"); + string Dist = Tags.FindS("Suite"); Dist = SubstVar(Dist,"$(ARCH)",_config->Find("APT::Architecture")); // Define external/internal options -- cgit v1.2.3 From a51fa92c521a6790446108a54ad1d9b6a16515ff Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 16 Jan 2014 17:03:07 +0100 Subject: rename URL to Uri in deb822-sources --- apt-pkg/sourcelist.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index ddebd206d..0cea8dc7f 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -78,7 +78,7 @@ bool pkgSourceList::Type::ParseStanza(vector &List, { map Options; - string URI = Tags.FindS("URL"); + string URI = Tags.FindS("Uri"); if (!FixupURI(URI)) { _error->Error(_("Malformed stanza %u in source list %s (URI parse)"),i,Fd.Name().c_str()); -- cgit v1.2.3 From d73743ddae1228bcd409700d8d0ffbe26e2e6cd1 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 16 Jan 2014 17:13:18 +0100 Subject: support multiple "Suite:" entries --- apt-pkg/sourcelist.cc | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 0cea8dc7f..09d8287a0 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -85,9 +85,6 @@ bool pkgSourceList::Type::ParseStanza(vector &List, return false; } - string Dist = Tags.FindS("Suite"); - Dist = SubstVar(Dist,"$(ARCH)",_config->Find("APT::Architecture")); - // Define external/internal options const char* option_deb822[] = { "Architectures", "Architectures-Add", "Architectures-Delete", "Trusted", @@ -99,13 +96,25 @@ bool pkgSourceList::Type::ParseStanza(vector &List, if (Tags.Exists(option_deb822[j])) Options[option_internal[j]] = Tags.FindS(option_deb822[j]); - // now create one item per section + // now create one item per suite/section + string Suite = Tags.FindS("Suite"); + Suite = SubstVar(Suite,"$(ARCH)",_config->Find("APT::Architecture")); string const Section = Tags.FindS("Section"); - std::vector list = StringSplit(Section, " "); - for (std::vector::const_iterator I = list.begin(); - I != list.end(); I++) - return CreateItem(List, URI, Dist, (*I), Options); - + + std::vector list_dist = StringSplit(Suite, " "); + std::vector list_section = StringSplit(Section, " "); + for (std::vector::const_iterator I = list_dist.begin(); + I != list_dist.end(); I++) + { + for (std::vector::const_iterator J = list_section.begin(); + J != list_section.end(); J++) + { + if (CreateItem(List, URI, (*I), (*J), Options) == false) + { + return false; + } + } + } return true; } -- cgit v1.2.3 From 62d8a765b9b37354efab6ca838cbdb7f347f7cac Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 16 Jan 2014 19:51:23 +0100 Subject: rework some code to fix some scan-build warnings No visible functional changes, just code moved around and additional checks to eliminate impossible branches Reported-By: scan-build Git-Dch: Ignore --- apt-pkg/aptconfiguration.cc | 4 ++-- apt-pkg/cacheset.cc | 2 ++ apt-pkg/contrib/gpgv.cc | 6 +++--- apt-pkg/contrib/mmap.cc | 8 +++++++- 4 files changed, 14 insertions(+), 6 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index 115d11616..1ebcf97bc 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -141,7 +141,7 @@ std::vector const Configuration::getLanguages(bool const &All, // so they will be all included in the Cache. std::vector builtin; DIR *D = opendir(_config->FindDir("Dir::State::lists").c_str()); - if (D != 0) { + if (D != NULL) { builtin.push_back("none"); for (struct dirent *Ent = readdir(D); Ent != 0; Ent = readdir(D)) { string const name = SubstVar(Ent->d_name, "%5f", "_"); @@ -166,8 +166,8 @@ std::vector const Configuration::getLanguages(bool const &All, continue; builtin.push_back(c); } + closedir(D); } - closedir(D); // FIXME: Remove support for the old APT::Acquire::Translation // it was undocumented and so it should be not very widthly used diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc index 0147f7e86..29281aab9 100644 --- a/apt-pkg/cacheset.cc +++ b/apt-pkg/cacheset.cc @@ -73,6 +73,8 @@ bool PackageContainerInterface::FromTask(PackageContainerInterface * const pci, const char *start, *end; parser.GetRec(start,end); unsigned int const length = end - start; + if (unlikely(length == 0)) + continue; char buf[length]; strncpy(buf, start, length); buf[length-1] = '\0'; diff --git a/apt-pkg/contrib/gpgv.cc b/apt-pkg/contrib/gpgv.cc index f57a72d86..0a469dd7a 100644 --- a/apt-pkg/contrib/gpgv.cc +++ b/apt-pkg/contrib/gpgv.cc @@ -103,12 +103,12 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG, } } + enum { DETACHED, CLEARSIGNED } releaseSignature = (FileGPG != File) ? DETACHED : CLEARSIGNED; std::vector dataHeader; char * sig = NULL; char * data = NULL; - // file with detached signature - if (FileGPG != File) + if (releaseSignature == DETACHED) { Args.push_back(FileGPG.c_str()); Args.push_back(File.c_str()); @@ -181,7 +181,7 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG, putenv((char *)"LC_MESSAGES="); } - if (FileGPG != File) + if (releaseSignature == DETACHED) { execvp(gpgvpath.c_str(), (char **) &Args[0]); ioprintf(std::cerr, "Couldn't execute %s to check %s", Args[0], File.c_str()); diff --git a/apt-pkg/contrib/mmap.cc b/apt-pkg/contrib/mmap.cc index a176da636..51e8eb30f 100644 --- a/apt-pkg/contrib/mmap.cc +++ b/apt-pkg/contrib/mmap.cc @@ -352,6 +352,12 @@ unsigned long DynamicMMap::RawAllocate(unsigned long long Size,unsigned long Aln size in the file. */ unsigned long DynamicMMap::Allocate(unsigned long ItemSize) { + if (unlikely(ItemSize == 0)) + { + _error->Fatal("Can't allocate an item of size zero"); + return 0; + } + // Look for a matching pool entry Pool *I; Pool *Empty = 0; @@ -412,7 +418,7 @@ unsigned long DynamicMMap::WriteString(const char *String, unsigned long const Result = RawAllocate(Len+1,0); - if (Result == 0 && _error->PendingError()) + if (Base == NULL || (Result == 0 && _error->PendingError())) return 0; memcpy((char *)Base + Result,String,Len); -- cgit v1.2.3 From 9ce3cfc9309c55cc01018c88c1ca82779fd74431 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 16 Jan 2014 22:19:49 +0100 Subject: correct some style/performance/warnings from cppcheck The most "visible" change is from utime to utimensat/futimens as the first one isn't part of POSIX anymore. Reported-By: cppcheck Git-Dch: Ignore --- apt-pkg/contrib/fileutl.cc | 2 +- apt-pkg/contrib/gpgv.cc | 5 ++--- apt-pkg/contrib/hashes.cc | 5 ++--- apt-pkg/contrib/hashsum.cc | 7 +++---- apt-pkg/deb/dpkgpm.cc | 9 +++------ apt-pkg/install-progress.cc | 2 +- 6 files changed, 12 insertions(+), 18 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index efbf7aaf4..1c8acd513 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -319,7 +319,7 @@ bool CreateDirectory(string const &Parent, string const &Path) return false; // we are not going to create directories "into the blue" - if (Path.find(Parent, 0) != 0) + if (Path.compare(0, Parent.length(), Parent) != 0) return false; vector const dirs = VectorizeString(Path.substr(Parent.size()), '/'); diff --git a/apt-pkg/contrib/gpgv.cc b/apt-pkg/contrib/gpgv.cc index 0a469dd7a..9de227062 100644 --- a/apt-pkg/contrib/gpgv.cc +++ b/apt-pkg/contrib/gpgv.cc @@ -260,8 +260,7 @@ bool SplitClearSignedFile(std::string const &InFile, FileFd * const ContentFile, char *buf = NULL; size_t buf_size = 0; - ssize_t line_len = 0; - while ((line_len = getline(&buf, &buf_size, in)) != -1) + while (getline(&buf, &buf_size, in) != -1) { _strrstrip(buf); if (found_message_start == false) @@ -355,7 +354,7 @@ bool OpenMaybeClearSignedFile(std::string const &ClearSignedFileName, FileFd &Me return _error->Error("Couldn't open temporary file to work with %s", ClearSignedFileName.c_str()); _error->PushToStack(); - bool const splitDone = SplitClearSignedFile(ClearSignedFileName.c_str(), &MessageFile, NULL, NULL); + bool const splitDone = SplitClearSignedFile(ClearSignedFileName, &MessageFile, NULL, NULL); bool const errorDone = _error->PendingError(); _error->MergeWithStack(); if (splitDone == false) diff --git a/apt-pkg/contrib/hashes.cc b/apt-pkg/contrib/hashes.cc index b4c768db9..890573d9c 100644 --- a/apt-pkg/contrib/hashes.cc +++ b/apt-pkg/contrib/hashes.cc @@ -129,13 +129,12 @@ bool Hashes::AddFD(int const Fd,unsigned long long Size, bool const addMD5, bool const addSHA1, bool const addSHA256, bool const addSHA512) { unsigned char Buf[64*64]; - ssize_t Res = 0; - int ToEOF = (Size == 0); + bool const ToEOF = (Size == 0); while (Size != 0 || ToEOF) { unsigned long long n = sizeof(Buf); if (!ToEOF) n = std::min(Size, n); - Res = read(Fd,Buf,n); + ssize_t const Res = read(Fd,Buf,n); if (Res < 0 || (!ToEOF && Res != (ssize_t) n)) // error, or short read return false; if (ToEOF && Res == 0) // EOF diff --git a/apt-pkg/contrib/hashsum.cc b/apt-pkg/contrib/hashsum.cc index 289e43aa4..d02177724 100644 --- a/apt-pkg/contrib/hashsum.cc +++ b/apt-pkg/contrib/hashsum.cc @@ -9,13 +9,12 @@ /* */ bool SummationImplementation::AddFD(int const Fd, unsigned long long Size) { unsigned char Buf[64 * 64]; - ssize_t Res = 0; - int ToEOF = (Size == 0); + bool const ToEOF = (Size == 0); while (Size != 0 || ToEOF) { unsigned long long n = sizeof(Buf); if (!ToEOF) n = std::min(Size, n); - Res = read(Fd, Buf, n); + ssize_t const Res = read(Fd, Buf, n); if (Res < 0 || (!ToEOF && Res != (ssize_t) n)) // error, or short read return false; if (ToEOF && Res == 0) // EOF @@ -27,7 +26,7 @@ bool SummationImplementation::AddFD(int const Fd, unsigned long long Size) { } bool SummationImplementation::AddFD(FileFd &Fd, unsigned long long Size) { unsigned char Buf[64 * 64]; - bool ToEOF = (Size == 0); + bool const ToEOF = (Size == 0); while (Size != 0 || ToEOF) { unsigned long long n = sizeof(Buf); diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 14ce133cf..1967d5d26 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -568,7 +568,6 @@ void pkgDPkgPM::ProcessDpkgStatusLine(char *line) std::string prefix = APT::String::Strip(list[0]); std::string pkgname; std::string action; - ostringstream status; // "processing" has the form "processing: action: pkg or trigger" // with action = ["install", "configure", "remove", "purge", "disappear", @@ -1652,7 +1651,7 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) io_errors.push_back(string("failed in write on buffer copy for %s")); io_errors.push_back(string("short read on buffer copy for %s")); - for (vector::iterator I = io_errors.begin(); I != io_errors.end(); I++) + for (vector::iterator I = io_errors.begin(); I != io_errors.end(); ++I) { vector list = VectorizeString(dgettext("dpkg", (*I).c_str()), '%'); if (list.size() > 1) { @@ -1767,13 +1766,11 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) string histfile_name = _config->FindFile("Dir::Log::History"); if (!histfile_name.empty()) { - FILE *log = NULL; - char buf[1024]; - fprintf(report, "DpkgHistoryLog:\n"); - log = fopen(histfile_name.c_str(),"r"); + FILE* log = fopen(histfile_name.c_str(),"r"); if(log != NULL) { + char buf[1024]; while( fgets(buf, sizeof(buf), log) != NULL) fprintf(report, " %s", buf); fclose(log); diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc index fe065da4f..a3a4cc0e1 100644 --- a/apt-pkg/install-progress.cc +++ b/apt-pkg/install-progress.cc @@ -242,7 +242,7 @@ PackageManagerFancy::~PackageManagerFancy() void PackageManagerFancy::staticSIGWINCH(int signum) { std::vector::const_iterator I; - for(I = instances.begin(); I != instances.end(); I++) + for(I = instances.begin(); I != instances.end(); ++I) (*I)->HandleSIGWINCH(signum); } -- cgit v1.2.3 From 866e9fadf892368fcb50e6a192bcdd350cfe8e5c Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 17 Jan 2014 20:41:55 +0100 Subject: implement suggestion by donkult (thanks!) --- apt-pkg/sourcelist.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 09d8287a0..51b766095 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -78,7 +78,7 @@ bool pkgSourceList::Type::ParseStanza(vector &List, { map Options; - string URI = Tags.FindS("Uri"); + string URI = Tags.FindS("URI"); if (!FixupURI(URI)) { _error->Error(_("Malformed stanza %u in source list %s (URI parse)"),i,Fd.Name().c_str()); @@ -87,7 +87,7 @@ bool pkgSourceList::Type::ParseStanza(vector &List, // Define external/internal options const char* option_deb822[] = { - "Architectures", "Architectures-Add", "Architectures-Delete", "Trusted", + "Architectures", "Architectures-Add", "Architectures-Remove", "Trusted", }; const char* option_internal[] = { "arch", "arch+", "arch-", "trusted", -- cgit v1.2.3 From 6c069a2247781754bcc8574687cb98b493c6ab8a Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 18 Jan 2014 20:51:03 +0100 Subject: rename "Suite/Section" to plural --- apt-pkg/sourcelist.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 51b766095..4e580ba04 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -97,9 +97,9 @@ bool pkgSourceList::Type::ParseStanza(vector &List, Options[option_internal[j]] = Tags.FindS(option_deb822[j]); // now create one item per suite/section - string Suite = Tags.FindS("Suite"); + string Suite = Tags.FindS("Suites"); Suite = SubstVar(Suite,"$(ARCH)",_config->Find("APT::Architecture")); - string const Section = Tags.FindS("Section"); + string const Section = Tags.FindS("Sections"); std::vector list_dist = StringSplit(Suite, " "); std::vector list_section = StringSplit(Section, " "); -- cgit v1.2.3 From 1700c3cfb902f3f61fa4d9269523467fcceaaf58 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 18 Jan 2014 23:42:51 +0100 Subject: do not ignore ioctl(TIOCSCTTY) errors Show a proper error message when a ioctl() in dpkgpm.cc fails. Also simply StartPtyMagic() a bit. --- apt-pkg/deb/dpkgpm.cc | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 14ce133cf..506ebf620 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1028,6 +1028,12 @@ bool pkgDPkgPM::Go(int StatusFd) void pkgDPkgPM::StartPtyMagic() { + if (_config->FindB("Dpkg::Use-Pty", true) == false) + { + d->master = d->slave = -1; + return; + } + // setup the pty and stuff struct winsize win; @@ -1036,10 +1042,9 @@ void pkgDPkgPM::StartPtyMagic() _error->PushToStack(); if (tcgetattr(STDOUT_FILENO, &d->tt) == 0) { - ioctl(1, TIOCGWINSZ, (char *)&win); - if (_config->FindB("Dpkg::Use-Pty", true) == false) + if (ioctl(1, TIOCGWINSZ, (char *)&win) < 0) { - d->master = d->slave = -1; + _error->Errno("ioctl", _("ioctl(TIOCGWINSZ) failed")); } else if (openpty(&d->master, &d->slave, NULL, &d->tt, &win) < 0) { _error->Errno("openpty", _("Can not write log (%s)"), _("Is /dev/pts mounted?")); @@ -1393,12 +1398,17 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress) if(d->slave >= 0 && d->master >= 0) { setsid(); - ioctl(d->slave, TIOCSCTTY, 0); - close(d->master); - dup2(d->slave, 0); - dup2(d->slave, 1); - dup2(d->slave, 2); - close(d->slave); + int res = ioctl(d->slave, TIOCSCTTY, 0); + if (res < 0) { + std::cerr << "ioctl(TIOCSCTTY) failed for fd: " + << d->slave << std::endl; + } else { + close(d->master); + dup2(d->slave, 0); + dup2(d->slave, 1); + dup2(d->slave, 2); + close(d->slave); + } } close(fd[0]); // close the read end of the pipe -- cgit v1.2.3 From 7dd62ea93413a73b4ec394b16ff4e0367d226395 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 20 Jan 2014 07:59:11 +0100 Subject: add support for Enabled: no in deb822 sources.list --- apt-pkg/sourcelist.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 4e580ba04..5d41fb00e 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -84,6 +84,10 @@ bool pkgSourceList::Type::ParseStanza(vector &List, _error->Error(_("Malformed stanza %u in source list %s (URI parse)"),i,Fd.Name().c_str()); return false; } + + string Enabled = Tags.FindS("Enabled"); + if (Enabled.size() > 0 && StringToBool(Enabled) == false) + return true; // Define external/internal options const char* option_deb822[] = { -- cgit v1.2.3 From 75c10df1533ede97e05fef3d1e2fc6a22fc4db00 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 20 Jan 2014 08:10:50 +0100 Subject: add support for multiple URIs in deb822 style sources.list --- apt-pkg/sourcelist.cc | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 5d41fb00e..339005149 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -78,13 +78,6 @@ bool pkgSourceList::Type::ParseStanza(vector &List, { map Options; - string URI = Tags.FindS("URI"); - if (!FixupURI(URI)) - { - _error->Error(_("Malformed stanza %u in source list %s (URI parse)"),i,Fd.Name().c_str()); - return false; - } - string Enabled = Tags.FindS("Enabled"); if (Enabled.size() > 0 && StringToBool(Enabled) == false) return true; @@ -104,20 +97,34 @@ bool pkgSourceList::Type::ParseStanza(vector &List, string Suite = Tags.FindS("Suites"); Suite = SubstVar(Suite,"$(ARCH)",_config->Find("APT::Architecture")); string const Section = Tags.FindS("Sections"); + string URIS = Tags.FindS("URIs"); + std::vector list_uris = StringSplit(URIS, " "); std::vector list_dist = StringSplit(Suite, " "); std::vector list_section = StringSplit(Section, " "); - for (std::vector::const_iterator I = list_dist.begin(); - I != list_dist.end(); I++) + + for (std::vector::const_iterator U = list_uris.begin(); + U != list_uris.end(); U++) { - for (std::vector::const_iterator J = list_section.begin(); - J != list_section.end(); J++) + std::string URI = (*U); + if (!FixupURI(URI)) + { + _error->Error(_("Malformed stanza %u in source list %s (URI parse)"),i,Fd.Name().c_str()); + return false; + } + + for (std::vector::const_iterator I = list_dist.begin(); + I != list_dist.end(); I++) + { + for (std::vector::const_iterator J = list_section.begin(); + J != list_section.end(); J++) { if (CreateItem(List, URI, (*I), (*J), Options) == false) { return false; } } + } } return true; } -- cgit v1.2.3 From 7f316a3feab95370f1dd28c08c58bc3c140bf0a0 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 20 Jan 2014 08:17:43 +0100 Subject: add support for multipl types in one line --- apt-pkg/sourcelist.cc | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 339005149..bbc514f5b 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -387,21 +387,26 @@ int pkgSourceList::ParseFileDeb822(string File) // read step by step while (Sources.Step(Tags) == true) { - if(!Tags.Exists("Type")) + if(!Tags.Exists("Types")) continue; - string const type = Tags.FindS("Type"); - Type *Parse = Type::GetType(type.c_str()); - if (Parse == 0) + string const types = Tags.FindS("Types"); + std::vector list_types = StringSplit(types, " "); + for (std::vector::const_iterator I = list_types.begin(); + I != list_types.end(); I++) { - _error->Error(_("Type '%s' is not known on stanza %u in source list %s"),type.c_str(),i,Fd.Name().c_str()); - return -1; - } + Type *Parse = Type::GetType((*I).c_str()); + if (Parse == 0) + { + _error->Error(_("Type '%s' is not known on stanza %u in source list %s"), (*I).c_str(),i,Fd.Name().c_str()); + return -1; + } - if (!Parse->ParseStanza(SrcList, Tags, i, Fd)) - return -1; + if (!Parse->ParseStanza(SrcList, Tags, i, Fd)) + return -1; - i++; + i++; + } } // we are done, return the number of stanzas read -- cgit v1.2.3 From 9e51c0b6a3a1a36336820eda11bcfd5534d9d80c Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 22 Jan 2014 17:18:26 +0100 Subject: "apt show" show user friendly size info The size/installed-size is displayed via SizeToStr() and Size is rewriten to "Download-Size" to make clear what size is refered to here. --- apt-pkg/tagfile.cc | 84 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 41 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc index bef3c76ba..b92b2c15a 100644 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@ -567,52 +567,54 @@ bool TFRewrite(FILE *Output,pkgTagSection const &Tags,const char *Order[], } // Write all all of the tags, in order. - for (unsigned int I = 0; Order[I] != 0; I++) + if (Order != NULL) { - bool Rewritten = false; - - // See if this is a field that needs to be rewritten - for (unsigned int J = 0; Rewrite != 0 && Rewrite[J].Tag != 0; J++) + for (unsigned int I = 0; Order[I] != 0; I++) { - if (strcasecmp(Rewrite[J].Tag,Order[I]) == 0) - { - Visited[J] |= 2; - if (Rewrite[J].Rewrite != 0 && Rewrite[J].Rewrite[0] != 0) - { - if (isspace(Rewrite[J].Rewrite[0])) - fprintf(Output,"%s:%s\n",Rewrite[J].NewTag,Rewrite[J].Rewrite); - else - fprintf(Output,"%s: %s\n",Rewrite[J].NewTag,Rewrite[J].Rewrite); - } - - Rewritten = true; - break; - } - } + bool Rewritten = false; + + // See if this is a field that needs to be rewritten + for (unsigned int J = 0; Rewrite != 0 && Rewrite[J].Tag != 0; J++) + { + if (strcasecmp(Rewrite[J].Tag,Order[I]) == 0) + { + Visited[J] |= 2; + if (Rewrite[J].Rewrite != 0 && Rewrite[J].Rewrite[0] != 0) + { + if (isspace(Rewrite[J].Rewrite[0])) + fprintf(Output,"%s:%s\n",Rewrite[J].NewTag,Rewrite[J].Rewrite); + else + fprintf(Output,"%s: %s\n",Rewrite[J].NewTag,Rewrite[J].Rewrite); + } + Rewritten = true; + break; + } + } - // See if it is in the fragment - unsigned Pos; - if (Tags.Find(Order[I],Pos) == false) - continue; - Visited[Pos] |= 1; - - if (Rewritten == true) - continue; + // See if it is in the fragment + unsigned Pos; + if (Tags.Find(Order[I],Pos) == false) + continue; + Visited[Pos] |= 1; + + if (Rewritten == true) + continue; - /* Write out this element, taking a moment to rewrite the tag - in case of changes of case. */ - const char *Start; - const char *Stop; - Tags.Get(Start,Stop,Pos); + /* Write out this element, taking a moment to rewrite the tag + in case of changes of case. */ + const char *Start; + const char *Stop; + Tags.Get(Start,Stop,Pos); - if (fputs(Order[I],Output) < 0) - return _error->Errno("fputs","IO Error to output"); - Start += strlen(Order[I]); - if (fwrite(Start,Stop - Start,1,Output) != 1) - return _error->Errno("fwrite","IO Error to output"); - if (Stop[-1] != '\n') - fprintf(Output,"\n"); - } + if (fputs(Order[I],Output) < 0) + return _error->Errno("fputs","IO Error to output"); + Start += strlen(Order[I]); + if (fwrite(Start,Stop - Start,1,Output) != 1) + return _error->Errno("fwrite","IO Error to output"); + if (Stop[-1] != '\n') + fprintf(Output,"\n"); + } + } // Now write all the old tags that were missed. for (unsigned int I = 0; I != Tags.Count(); I++) -- cgit v1.2.3 From 655af1e137385aa41c5505edc350111e9f8762ca Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 24 Jan 2014 23:17:30 +0100 Subject: set APT::Sources::Use-Deb822 to default false for now --- apt-pkg/sourcelist.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index bbc514f5b..ac326d157 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -297,7 +297,7 @@ bool pkgSourceList::Read(string File) /* */ bool pkgSourceList::ReadAppend(string File) { - if (_config->FindB("APT::Sources::Use-Deb822", true) == true) + if (_config->FindB("APT::Sources::Use-Deb822", false) == true) { int lines_parsed =ParseFileDeb822(File); if (lines_parsed < 0) -- cgit v1.2.3 From 41e6bd080db8995bc7617569f0719bccc31e0da8 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 25 Jan 2014 14:53:03 +0100 Subject: support " " in deb822 source options --- apt-pkg/sourcelist.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index 4e580ba04..8462027c5 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -20,6 +20,7 @@ #include #include +#include #include /*}}}*/ @@ -94,7 +95,12 @@ bool pkgSourceList::Type::ParseStanza(vector &List, }; for (unsigned int j=0; j < sizeof(option_deb822)/sizeof(char*); j++) if (Tags.Exists(option_deb822[j])) - Options[option_internal[j]] = Tags.FindS(option_deb822[j]); + { + // for deb822 the " " is the delimiter, but the backend expects "," + std::string option = Tags.FindS(option_deb822[j]); + std::replace(option.begin(), option.end(), ' ', ','); + Options[option_internal[j]] = option; + } // now create one item per suite/section string Suite = Tags.FindS("Suites"); -- cgit v1.2.3 From e62aa1dd8099aeb8bb667253ca22c56b93f521d1 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 29 Jan 2014 23:02:51 +0100 Subject: pkgTagFile: if we have seen the end, do not try to see more Asking for more via Step() will notice that we are done with the file already and will result in a fail, which means we can't find the last sections anymore (which is especially painful if we haven't moved at all as in the testcase we haven't even looked at one of the sources leading to a strange behaviour) Reported-By: Niall Walsh --- apt-pkg/tagfile.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc index b92b2c15a..832a40d1e 100644 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@ -207,7 +207,11 @@ bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long long Offset) unsigned long long Dist = Offset - d->iOffset; d->Start += Dist; d->iOffset += Dist; - return Step(Tag); + // if we have seen the end, don't ask for more + if (d->Done == true) + return Tag.Scan(d->Start, d->End - d->Start); + else + return Step(Tag); } // Reposition and reload.. -- cgit v1.2.3 From 6a9c9d63edc878ff268cdaa4f985ca50c48380b0 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 29 Jan 2014 23:24:41 +0100 Subject: restart debSrcRecordParsers only if needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The offset variable in DebSrcRecordParser was not initialized which we now do and based on it do not trigger a restart if the parser was not used yet avoiding a needless rescan of the section. Detected while working on the previous commit e62aa1dd. Both commits act as a "fix" for the bug shown in the testcase of the commit – this one here would only hide it through. --- apt-pkg/deb/debsrcrecords.h | 6 +++--- apt-pkg/srcrecords.cc | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/deb/debsrcrecords.h b/apt-pkg/deb/debsrcrecords.h index 5d2a67f4f..a8fb465bb 100644 --- a/apt-pkg/deb/debsrcrecords.h +++ b/apt-pkg/deb/debsrcrecords.h @@ -30,7 +30,7 @@ class debSrcRecordParser : public pkgSrcRecords::Parser public: - virtual bool Restart() {return Tags.Jump(Sect,0);}; + virtual bool Restart() {return Jump(0);}; virtual bool Step() {iOffset = Tags.Offset(); return Tags.Step(Sect);}; virtual bool Jump(unsigned long const &Off) {iOffset = Off; return Tags.Jump(Sect,Off);}; @@ -50,8 +50,8 @@ class debSrcRecordParser : public pkgSrcRecords::Parser virtual bool Files(std::vector &F); debSrcRecordParser(std::string const &File,pkgIndexFile const *Index) - : Parser(Index), Fd(File,FileFd::ReadOnly, FileFd::Extension), Tags(&Fd,102400), - Buffer(NULL) {} + : Parser(Index), Fd(File,FileFd::ReadOnly, FileFd::Extension), Tags(&Fd,102400), + iOffset(0), Buffer(NULL) {} virtual ~debSrcRecordParser(); }; diff --git a/apt-pkg/srcrecords.cc b/apt-pkg/srcrecords.cc index 297559957..60b62850a 100644 --- a/apt-pkg/srcrecords.cc +++ b/apt-pkg/srcrecords.cc @@ -70,8 +70,9 @@ bool pkgSrcRecords::Restart() Current = Files.begin(); for (std::vector::iterator I = Files.begin(); I != Files.end(); ++I) - (*I)->Restart(); - + if ((*I)->Offset() != 0) + (*I)->Restart(); + return true; } /*}}}*/ -- cgit v1.2.3 From 0dfc7eef47519bd6b48ceaa4341b72ec40560988 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 4 Feb 2014 10:18:16 +0100 Subject: Fix multiarch package upgrade issue When checking for negative dependencies in MarkInstall() ensure that only dependencies that are relevant (i.e. getting installed) are checked. --- apt-pkg/depcache.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index f9c891c86..a3bb4fd3d 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1253,6 +1253,11 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, if (PkgState[Pkg->ID].InstallVer == 0) continue; + /* Ignore negative dependencies that we are not going to + get installed */ + if (PkgState[Pkg->ID].InstallVer != *I) + continue; + if ((Start->Version != 0 || TrgPkg != Pkg) && PkgState[Pkg->ID].CandidateVer != PkgState[Pkg->ID].InstallVer && PkgState[Pkg->ID].CandidateVer != *I && -- cgit v1.2.3 From 446551c8ffd2c9cb9dcd707c94590e73009f7dd9 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 6 Feb 2014 00:13:10 +0100 Subject: discard impossible candidates in MarkInstall If a (Pre-)Depends can't be satisfied there is no point in keeping the candidate as is as it is impossible to find a solution for it, so we can just as well reset the candidate to the currently installed version. We avoid trying to install this impossible candidate later on this way. Closes: #735967 --- apt-pkg/depcache.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index f9c891c86..7e75a6fe3 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1134,8 +1134,13 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, std::clog << OutputInDepth(Depth) << Start << " can't be satisfied!" << std::endl; if (Start.IsCritical() == false) continue; - // if the dependency was critical, we can't install it, so remove it again - MarkDelete(Pkg,false,Depth + 1, false); + // if the dependency was critical, we have absolutely no chance to install it, + // so if it wasn't installed remove it again. If it was, discard the candidate + // as the problemresolver will trip over it otherwise trying to install it (#735967) + if (Pkg->CurrentVer == 0) + MarkDelete(Pkg,false,Depth + 1, false); + else + SetCandidateVersion(Pkg.CurrentVer()); return false; } -- cgit v1.2.3 From 6008b79adf1d7ea5607fab87a355d664c8725026 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 6 Feb 2014 21:46:29 +0100 Subject: simplify code to make compilers happy Does the same as before, but is a bit simpler on the logic for humans as well as compilers. scan-build complained about it at least with: "Result of operation is garbage or undefined" Reported-By: scan-build --- apt-pkg/contrib/fileutl.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 37155b688..71ac9c73f 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -1594,11 +1594,17 @@ unsigned long long FileFd::Tell() unsigned long long FileFd::FileSize() { struct stat Buf; - if ((d == NULL || d->pipe == false) && fstat(iFd,&Buf) != 0) - return FileFdErrno("fstat","Unable to determine the file size"); + + bool ispipe = (d != NULL && d->pipe == true); + if (ispipe == false) + { + if (fstat(iFd,&Buf) != 0) + return FileFdErrno("fstat","Unable to determine the file size"); + ispipe = S_ISFIFO(Buf.st_mode); + } // for compressor pipes st_size is undefined and at 'best' zero - if ((d != NULL && d->pipe == true) || S_ISFIFO(Buf.st_mode)) + if (ispipe == true) { // we set it here, too, as we get the info here for free // in theory the Open-methods should take care of it already -- cgit v1.2.3 From 436bcfbb16ce558c228a3a6e29ad77c0c62664bc Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 10 Feb 2014 14:42:56 +0100 Subject: do not use an empty APT_CONFIG environment variable --- apt-pkg/init.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/init.cc b/apt-pkg/init.cc index 81b601a7f..6ab5ec42d 100644 --- a/apt-pkg/init.cc +++ b/apt-pkg/init.cc @@ -92,7 +92,7 @@ bool pkgInitConfig(Configuration &Cnf) // Read an alternate config file const char *Cfg = getenv("APT_CONFIG"); - if (Cfg != 0) + if (Cfg != 0 && strlen(Cfg) != 0) { if (RealFileExists(Cfg) == true) Res &= ReadConfigFile(Cnf,Cfg); -- cgit v1.2.3 From 34d6ece7566ea4fcda2286478b31641378aefc93 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 10 Feb 2014 17:55:13 +0100 Subject: always cleanup patchfiles at the end of rred call With APT::Get::List-Cleanup disabled the ed-style patch files are lingering in the lists/ directory otherwise. That was kinda okay in the old none-client-merge as the filename was always the same so it was constantly overridden, but now with different names for client-merge quiet a few could pill up on the system and are used by the next call as it picks them up based on the filename. --- apt-pkg/acquire-item.cc | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 1185908f3..60003c023 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -757,6 +757,7 @@ void pkgAcqIndexDiffs::Done(string Message,unsigned long long Size,string Md5Has { // remove the just applied patch available_patches.erase(available_patches.begin()); + unlink((FinalFile + ".ed").c_str()); // move into place if(Debug) @@ -887,6 +888,14 @@ void pkgAcqIndexMergeDiffs::Done(string Message,unsigned long long Size,string M // otherwise lists cleanup will eat the file DestFile = FinalFile; + // ensure the ed's are gone regardless of list-cleanup + for (std::vector::const_iterator I = allPatches->begin(); + I != allPatches->end(); ++I) + { + std::string patch = FinalFile + ".ed." + (*I)->patch.file + ".gz"; + unlink(patch.c_str()); + } + // all set and done Complete = true; if(Debug) -- cgit v1.2.3 From 62dcbf84c4aee8cb01e40c594d4c7f3a23b64836 Mon Sep 17 00:00:00 2001 From: John Ogness Date: Fri, 13 Dec 2013 20:59:31 +0100 Subject: apt-cdrom should succeed if any drive succeeds If there are multiple CD-ROM drives, `apt-cdrom add` will abort with an error if any of the drives do not contain a Debian CD which is against the documentation we have saying "a CD-ROM" and also scripts do not expect it this way. This patch modifies apt-cdrom to return success if any of the drives succeeded. If failures occur, apt-cdrom will still continue trying all the drives and report the last failure (if none of them succeeded). The 'ident' command was also changed to match the new 'add' behavior. Closes: 728153 --- apt-pkg/cdrom.cc | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cdrom.cc b/apt-pkg/cdrom.cc index a5668a50a..f577e3572 100644 --- a/apt-pkg/cdrom.cc +++ b/apt-pkg/cdrom.cc @@ -577,8 +577,30 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log) /*{{{*/ CDROM.c_str()); log->Update(msg.str()); } - if (MountCdrom(CDROM) == false) - return _error->Error("Failed to mount the cdrom."); + + // Unmount the CD and get the user to put in the one they want + if (_config->FindB("APT::CDROM::NoMount",false) == false) + { + if(log != NULL) + log->Update(_("Unmounting CD-ROM\n"), STEP_UNMOUNT); + UnmountCdrom(CDROM); + + if(log != NULL) + { + log->Update(_("Waiting for disc...\n"), STEP_WAIT); + if(!log->ChangeCdrom()) { + // user aborted + return false; + } + } + + // Mount the new CDROM + if(log != NULL) + log->Update(_("Mounting CD-ROM...\n"), STEP_MOUNT); + + if (MountCdrom(CDROM) == false) + return _error->Error("Failed to mount the cdrom."); + } // Hash the CD to get an ID if (log != NULL) -- cgit v1.2.3 From ce55512d4924b52c985276c62a0c69ac13e203cd Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 12 Feb 2014 02:12:40 +0100 Subject: remove duplication in pkgCdrom::Add and ::Ident Git-Dch: Ignore --- apt-pkg/cdrom.cc | 131 +++++++++++++++++-------------------------------------- apt-pkg/cdrom.h | 4 ++ 2 files changed, 45 insertions(+), 90 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cdrom.cc b/apt-pkg/cdrom.cc index f577e3572..3ae1e8b1d 100644 --- a/apt-pkg/cdrom.cc +++ b/apt-pkg/cdrom.cc @@ -561,25 +561,23 @@ bool pkgCdrom::WriteSourceList(string Name,vector &List,bool Source) return true; } /*}}}*/ -bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log) /*{{{*/ +bool pkgCdrom::MountAndIdentCDROM(Configuration &Database, std::string &CDROM, std::string &ident, pkgCdromStatus * const log)/*{{{*/ { - stringstream msg; - // Startup - string CDROM = _config->FindDir("Acquire::cdrom::mount"); + CDROM = _config->FindDir("Acquire::cdrom::mount"); if (CDROM[0] == '.') CDROM= SafeGetCWD() + '/' + CDROM; if (log != NULL) { - msg.str(""); - ioprintf(msg, _("Using CD-ROM mount point %s\nMounting CD-ROM\n"), - CDROM.c_str()); - log->Update(msg.str()); + string msg; + log->SetTotal(STEP_LAST); + strprintf(msg, _("Using CD-ROM mount point %s\n"), CDROM.c_str()); + log->Update(msg, STEP_PREPARE); } // Unmount the CD and get the user to put in the one they want - if (_config->FindB("APT::CDROM::NoMount",false) == false) + if (_config->FindB("APT::CDROM::NoMount", false) == false) { if(log != NULL) log->Update(_("Unmounting CD-ROM\n"), STEP_UNMOUNT); @@ -604,24 +602,24 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log) /*{{{*/ // Hash the CD to get an ID if (log != NULL) - log->Update(_("Identifying.. ")); - + log->Update(_("Identifying.. "), STEP_IDENT); if (IdentCdrom(CDROM,ident) == false) { ident = ""; + if (log != NULL) + log->Update("\n"); return false; } if (log != NULL) { - msg.str(""); - ioprintf(msg, "[%s]\n",ident.c_str()); - log->Update(msg.str()); + string msg; + strprintf(msg, "[%s]\n", ident.c_str()); + log->Update(msg); } // Read the database - Configuration Database; string DFile = _config->FindFile("Dir::State::cdroms"); if (FileExists(DFile) == true) { @@ -629,12 +627,22 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log) /*{{{*/ return _error->Error("Unable to read the cdrom database %s", DFile.c_str()); } + return true; +} + /*}}}*/ +bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log) /*{{{*/ +{ + Configuration Database; + std::string CDROM; + if (MountAndIdentCDROM(Database, CDROM, ident, log) == false) + return false; + if (log != NULL) { - msg.str(""); - ioprintf(msg, _("Stored label: %s\n"), - Database.Find("CD::"+ident).c_str()); - log->Update(msg.str()); + string msg; + strprintf(msg, _("Stored label: %s\n"), + Database.Find("CD::"+ident).c_str()); + log->Update(msg); } // Unmount and finish @@ -650,70 +658,13 @@ bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log) /*{{{*/ /*}}}*/ bool pkgCdrom::Add(pkgCdromStatus *log) /*{{{*/ { - stringstream msg; - - // Startup - string CDROM = _config->FindDir("Acquire::cdrom::mount"); - if (CDROM[0] == '.') - CDROM= SafeGetCWD() + '/' + CDROM; - - if(log != NULL) - { - log->SetTotal(STEP_LAST); - msg.str(""); - ioprintf(msg, _("Using CD-ROM mount point %s\n"), CDROM.c_str()); - log->Update(msg.str(), STEP_PREPARE); - } - - // Read the database Configuration Database; - string DFile = _config->FindFile("Dir::State::cdroms"); - if (FileExists(DFile) == true) - { - if (ReadConfigFile(Database,DFile) == false) - return _error->Error("Unable to read the cdrom database %s", - DFile.c_str()); - } - - // Unmount the CD and get the user to put in the one they want - if (_config->FindB("APT::CDROM::NoMount",false) == false) - { - if(log != NULL) - log->Update(_("Unmounting CD-ROM\n"), STEP_UNMOUNT); - UnmountCdrom(CDROM); - - if(log != NULL) - { - log->Update(_("Waiting for disc...\n"), STEP_WAIT); - if(!log->ChangeCdrom()) { - // user aborted - return false; - } - } - - // Mount the new CDROM - if(log != NULL) - log->Update(_("Mounting CD-ROM...\n"), STEP_MOUNT); - - if (MountCdrom(CDROM) == false) - return _error->Error("Failed to mount the cdrom."); - } - - // Hash the CD to get an ID - if(log != NULL) - log->Update(_("Identifying.. "), STEP_IDENT); - string ID; - if (IdentCdrom(CDROM,ID) == false) - { - if (log != NULL) - log->Update("\n"); + std::string ID, CDROM; + if (MountAndIdentCDROM(Database, CDROM, ID, log) == false) return false; - } + if(log != NULL) - { - log->Update("["+ID+"]\n"); log->Update(_("Scanning disc for index files..\n"),STEP_SCAN); - } // Get the CD structure vector List; @@ -762,12 +713,12 @@ bool pkgCdrom::Add(pkgCdromStatus *log) /*{{{*/ if (_config->FindB("APT::CDROM::DropTranslation", true) == true) DropTranslation(TransList); if(log != NULL) { - msg.str(""); - ioprintf(msg, _("Found %zu package indexes, %zu source indexes, " + string msg; + strprintf(msg, _("Found %zu package indexes, %zu source indexes, " "%zu translation indexes and %zu signatures\n"), List.size(), SourceList.size(), TransList.size(), SigList.size()); - log->Update(msg.str(), STEP_SCAN); + log->Update(msg, STEP_SCAN); } if (List.empty() == true && SourceList.empty() == true) @@ -800,9 +751,9 @@ bool pkgCdrom::Add(pkgCdromStatus *log) /*{{{*/ if(log != NULL) { - msg.str(""); - ioprintf(msg, _("Found label '%s'\n"), Name.c_str()); - log->Update(msg.str()); + string msg; + strprintf(msg, _("Found label '%s'\n"), Name.c_str()); + log->Update(msg); } Database.Set("CD::" + ID + "::Label",Name); } @@ -846,9 +797,9 @@ bool pkgCdrom::Add(pkgCdromStatus *log) /*{{{*/ Database.Set("CD::" + ID,Name); if(log != NULL) { - msg.str(""); - ioprintf(msg, _("This disc is called: \n'%s'\n"), Name.c_str()); - log->Update(msg.str()); + string msg; + strprintf(msg, _("This disc is called: \n'%s'\n"), Name.c_str()); + log->Update(msg); log->Update(_("Copying package lists..."), STEP_COPY); } @@ -906,7 +857,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log) /*{{{*/ if(log != NULL) { - msg.str(""); + stringstream msg; msg << "deb cdrom:[" << Name << "]/" << string(*I,0,Space) << " " << string(*I,Space+1) << endl; log->Update(msg.str()); @@ -924,7 +875,7 @@ bool pkgCdrom::Add(pkgCdromStatus *log) /*{{{*/ } if(log != NULL) { - msg.str(""); + stringstream msg; msg << "deb-src cdrom:[" << Name << "]/" << string(*I,0,Space) << " " << string(*I,Space+1) << endl; log->Update(msg.str()); diff --git a/apt-pkg/cdrom.h b/apt-pkg/cdrom.h index 7d19eb813..db637b96d 100644 --- a/apt-pkg/cdrom.h +++ b/apt-pkg/cdrom.h @@ -69,6 +69,10 @@ class pkgCdrom /*{{{*/ public: bool Ident(std::string &ident, pkgCdromStatus *log); bool Add(pkgCdromStatus *log); + + private: + bool MountAndIdentCDROM(Configuration &Database, std::string &CDROM, + std::string &ident, pkgCdromStatus * const log); }; /*}}}*/ -- cgit v1.2.3 From 9082a1fc7be02f58cbe18a34539c6a3436463dd0 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 14 Feb 2014 00:30:58 +0100 Subject: allow http protocol to switch to https switch protocols at random is a bad idea if e.g. http can switch to file, so we limit the possibilities to http to http and http to https. As very few people (less than 1% according to popcon) have https installed this likely changes nothing in terms of failure. The commit is adding a friendly hint which package needs to be installed though. --- apt-pkg/acquire-worker.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-worker.cc b/apt-pkg/acquire-worker.cc index 44a84216a..44c3e4e17 100644 --- a/apt-pkg/acquire-worker.cc +++ b/apt-pkg/acquire-worker.cc @@ -109,7 +109,12 @@ bool pkgAcquire::Worker::Start() // Get the method path string Method = _config->FindDir("Dir::Bin::Methods") + Access; if (FileExists(Method) == false) - return _error->Error(_("The method driver %s could not be found."),Method.c_str()); + { + _error->Error(_("The method driver %s could not be found."),Method.c_str()); + if (Access == "https") + _error->Notice(_("Is the package %s installed?"), "apt-transport-https"); + return false; + } if (Debug == true) clog << "Starting method '" << Method << '\'' << endl; -- cgit v1.2.3 From 8190b07a4b338e005fa30d769cb34f1fd29eaa45 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 14 Feb 2014 16:33:26 +0100 Subject: simplify code some more to make reddit happy Commit 6008b79adf1d7ea5607fab87a355d664c8725026 should have been guarded by "Git-Dch: Ignore", but it wasn't and I only noticed it with the Close message via deity thinking "hehe, I wonder if someone is gonna notice". Looks like someone did: hats off to reddit user itisOmegakai! Good to know that what I do isn't only monitored by goverments. :) As there is another instance of basically the same code we just factor out the code a bit and reuse, so its even cleaner and not only simpler. Reported-By: scan-build --- apt-pkg/contrib/fileutl.cc | 67 ++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 38 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 71ac9c73f..536284064 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -1588,18 +1588,15 @@ unsigned long long FileFd::Tell() return Res; } /*}}}*/ -// FileFd::FileSize - Return the size of the file /*{{{*/ -// --------------------------------------------------------------------- -/* */ -unsigned long long FileFd::FileSize() +static bool StatFileFd(char const * const msg, int const iFd, std::string const &FileName, struct stat &Buf, FileFdPrivate * const d) /*{{{*/ { - struct stat Buf; - bool ispipe = (d != NULL && d->pipe == true); if (ispipe == false) { if (fstat(iFd,&Buf) != 0) - return FileFdErrno("fstat","Unable to determine the file size"); + // higher-level code will generate more meaningful messages, + // even translated this would be meaningless for users + return _error->Errno("fstat", "Unable to determine %s for fd %i", msg, iFd); ispipe = S_ISFIFO(Buf.st_mode); } @@ -1611,12 +1608,35 @@ unsigned long long FileFd::FileSize() if (d != NULL) d->pipe = true; if (stat(FileName.c_str(), &Buf) != 0) - return FileFdErrno("stat","Unable to determine the file size"); + return _error->Errno("fstat", "Unable to determine %s for file %s", msg, FileName.c_str()); + } + return true; +} + /*}}}*/ +// FileFd::FileSize - Return the size of the file /*{{{*/ +unsigned long long FileFd::FileSize() +{ + struct stat Buf; + if (StatFileFd("file size", iFd, FileName, Buf, d) == false) + { + Flags |= Fail; + return 0; } - return Buf.st_size; } /*}}}*/ +// FileFd::ModificationTime - Return the time of last touch /*{{{*/ +time_t FileFd::ModificationTime() +{ + struct stat Buf; + if (StatFileFd("modification time", iFd, FileName, Buf, d) == false) + { + Flags |= Fail; + return 0; + } + return Buf.st_mtime; +} + /*}}}*/ // FileFd::Size - Return the size of the content in the file /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -1688,35 +1708,6 @@ unsigned long long FileFd::Size() return size; } /*}}}*/ -// FileFd::ModificationTime - Return the time of last touch /*{{{*/ -// --------------------------------------------------------------------- -/* */ -time_t FileFd::ModificationTime() -{ - struct stat Buf; - if ((d == NULL || d->pipe == false) && fstat(iFd,&Buf) != 0) - { - FileFdErrno("fstat","Unable to determine the modification time of file %s", FileName.c_str()); - return 0; - } - - // for compressor pipes st_size is undefined and at 'best' zero - if ((d != NULL && d->pipe == true) || S_ISFIFO(Buf.st_mode)) - { - // we set it here, too, as we get the info here for free - // in theory the Open-methods should take care of it already - if (d != NULL) - d->pipe = true; - if (stat(FileName.c_str(), &Buf) != 0) - { - FileFdErrno("fstat","Unable to determine the modification time of file %s", FileName.c_str()); - return 0; - } - } - - return Buf.st_mtime; -} - /*}}}*/ // FileFd::Close - Close the file if the close flag is set /*{{{*/ // --------------------------------------------------------------------- /* */ -- cgit v1.2.3 From 16724b66fef02208ef050a36f732991941e39025 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 14 Feb 2014 19:40:58 +0100 Subject: add missing canNotFindFnmatch/showFnmatchSelection (for the next ABI break) --- apt-pkg/cacheset.cc | 25 +++++++++++++++++++++++-- apt-pkg/cacheset.h | 6 ++++++ 2 files changed, 29 insertions(+), 2 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc index 29281aab9..1b1e6d595 100644 --- a/apt-pkg/cacheset.cc +++ b/apt-pkg/cacheset.cc @@ -204,12 +204,20 @@ PackageContainerInterface::FromFnmatch(PackageContainerInterface * const pci, } pci->insert(Pkg); +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) + helper.showFnmatchSelection(Pkg, pattern); +#else helper.showRegExSelection(Pkg, pattern); +#endif found = true; } if (found == false) { - helper.canNotFindRegEx(pci, Cache, pattern); +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) + helper.canNotFindFnmatch(pci, Cache, pattern); +#else + helper.canNotFindRegEx(pci, Cache, pattern); +#endif pci->setConstructor(UNKNOWN); return false; } @@ -588,7 +596,13 @@ void CacheSetHelper::canNotFindRegEx(PackageContainerInterface * const pci, pkgC if (ShowError == true) _error->Insert(ErrorType, _("Couldn't find any package by regex '%s'"), pattern.c_str()); } - /*}}}*/ +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) +// canNotFindFnmatch - handle the case no package is found by a fnmatch /*{{{*/ +void CacheSetHelper::canNotFindFnmatch(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern) { + if (ShowError == true) + _error->Insert(ErrorType, _("Couldn't find any package by glob '%s'"), pattern.c_str()); +} +#endif /*}}}*/ // canNotFindPackage - handle the case no package is found from a string/*{{{*/ void CacheSetHelper::canNotFindPackage(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &str) { } @@ -648,6 +662,13 @@ void CacheSetHelper::showRegExSelection(pkgCache::PkgIterator const &pkg, std::string const &pattern) { } /*}}}*/ +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) +// showFnmatchSelection /*{{{*/ +void CacheSetHelper::showFnmatchSelection(pkgCache::PkgIterator const &pkg, + std::string const &pattern) { +} + /*}}}*/ +#endif // showSelectedVersion /*{{{*/ void CacheSetHelper::showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver, diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h index 29103aad9..b69d74b8e 100644 --- a/apt-pkg/cacheset.h +++ b/apt-pkg/cacheset.h @@ -48,11 +48,17 @@ public: /*{{{*/ virtual void showTaskSelection(pkgCache::PkgIterator const &pkg, std::string const &pattern); virtual void showRegExSelection(pkgCache::PkgIterator const &pkg, std::string const &pattern); +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) + virtual void showFnmatchSelection(pkgCache::PkgIterator const &pkg, std::string const &pattern); +#endif virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver, std::string const &ver, bool const verIsRel); virtual void canNotFindTask(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern); virtual void canNotFindRegEx(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern); +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) + virtual void canNotFindFnmatch(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string pattern); +#endif virtual void canNotFindPackage(PackageContainerInterface * const pci, pkgCacheFile &Cache, std::string const &str); virtual void canNotFindAllVer(VersionContainerInterface * const vci, pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg); -- cgit v1.2.3 From 32611903e8dcd6599042552c6c576b70e3d6633a Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 14 Feb 2014 19:58:56 +0100 Subject: disable fnmatch() The current PackageContainerInterface::FromString() will do a FromFnmatch() first and then FromRegEx(). This commit reverts that change to restore the old behavior to only look for RegEx and not glob-style pattern. The rational is that: a) currently a fnmatch() is misleadingly reported as a regex match to the user (Bug#738880) b) a fnmatch may match something different than a a RegEx so the change broke a published interface --- apt-pkg/cacheset.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc index 1b1e6d595..eab1e09f8 100644 --- a/apt-pkg/cacheset.cc +++ b/apt-pkg/cacheset.cc @@ -312,7 +312,6 @@ bool PackageContainerInterface::FromString(PackageContainerInterface * const pci if (FromGroup(pci, Cache, str, helper) == false && FromTask(pci, Cache, str, helper) == false && - FromFnmatch(pci, Cache, str, helper) == false && FromRegEx(pci, Cache, str, helper) == false) { helper.canNotFindPackage(pci, Cache, str); -- cgit v1.2.3 From 7e75a619f6d35c492c1341096096432109facfc5 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 20 Feb 2014 14:41:24 +0100 Subject: prepare re-enable fnmatch() once we have proper reporting --- apt-pkg/cacheset.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'apt-pkg') diff --git a/apt-pkg/cacheset.cc b/apt-pkg/cacheset.cc index eab1e09f8..6b6fdb5ad 100644 --- a/apt-pkg/cacheset.cc +++ b/apt-pkg/cacheset.cc @@ -312,6 +312,9 @@ bool PackageContainerInterface::FromString(PackageContainerInterface * const pci if (FromGroup(pci, Cache, str, helper) == false && FromTask(pci, Cache, str, helper) == false && +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) + FromFnmatch(pci, Cache, str, helper) == false) +#endif FromRegEx(pci, Cache, str, helper) == false) { helper.canNotFindPackage(pci, Cache, str); -- cgit v1.2.3 From 1e3f4083db29bba600b9725e9456b0e140975c99 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 22 Feb 2014 18:34:33 +0100 Subject: Fix typos in documentation (codespell) --- apt-pkg/acquire-item.cc | 20 ++++++++++---------- apt-pkg/acquire-worker.cc | 2 +- apt-pkg/acquire.cc | 6 +++--- apt-pkg/algorithms.cc | 12 ++++++------ apt-pkg/algorithms.h | 4 ++-- apt-pkg/aptconfiguration.cc | 8 ++++---- apt-pkg/aptconfiguration.h | 10 +++++----- apt-pkg/cacheiterators.h | 6 +++--- apt-pkg/cdrom.h | 2 +- apt-pkg/clean.cc | 2 +- apt-pkg/contrib/cdromutl.cc | 4 ++-- apt-pkg/contrib/cmndline.cc | 2 +- apt-pkg/contrib/crc-16.cc | 2 +- apt-pkg/contrib/error.h | 2 +- apt-pkg/contrib/fileutl.cc | 6 +++--- apt-pkg/contrib/gpgv.h | 2 +- apt-pkg/contrib/macros.h | 2 +- apt-pkg/contrib/md5.h | 2 +- apt-pkg/contrib/mmap.h | 4 ++-- apt-pkg/contrib/progress.h | 2 +- apt-pkg/contrib/sha2_internal.cc | 2 +- apt-pkg/contrib/strutl.cc | 10 +++++----- apt-pkg/deb/deblistparser.cc | 2 +- apt-pkg/deb/debsystem.cc | 2 +- apt-pkg/deb/debversion.cc | 4 ++-- apt-pkg/depcache.cc | 6 +++--- apt-pkg/depcache.h | 2 +- apt-pkg/edsp.h | 6 +++--- apt-pkg/indexfile.h | 4 ++-- apt-pkg/orderlist.cc | 8 ++++---- apt-pkg/packagemanager.cc | 16 ++++++++-------- apt-pkg/pkgcache.cc | 4 ++-- apt-pkg/pkgcache.h | 2 +- apt-pkg/pkgsystem.h | 4 ++-- apt-pkg/upgrade.cc | 2 +- 35 files changed, 87 insertions(+), 87 deletions(-) (limited to 'apt-pkg') diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 60003c023..36bb48382 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -129,7 +129,7 @@ void pkgAcquire::Item::Done(string Message,unsigned long long Size,string Hash, /*}}}*/ // Acquire::Item::Rename - Rename a file /*{{{*/ // --------------------------------------------------------------------- -/* This helper function is used by alot of item methods as thier final +/* This helper function is used by a lot of item methods as their final step */ void pkgAcquire::Item::Rename(string From,string To) { @@ -299,7 +299,7 @@ void pkgAcqSubIndex::Done(string Message,unsigned long long Size,string Md5Hash, return; } - // sucess in downloading the index + // success in downloading the index // rename the index if(Debug) std::clog << "Renaming: " << DestFile << " -> " << FinalFile << std::endl; @@ -327,7 +327,7 @@ bool pkgAcqSubIndex::ParseIndex(string const &IndexFile) /*{{{*/ /*}}}*/ // AcqDiffIndex::AcqDiffIndex - Constructor /*{{{*/ // --------------------------------------------------------------------- -/* Get the DiffIndex file first and see if there are patches availabe +/* Get the DiffIndex file first and see if there are patches available * If so, create a pkgAcqIndexDiffs fetcher that will get and apply the * patches. If anything goes wrong in that process, it will fall back to * the original packages file @@ -548,7 +548,7 @@ void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{ { if(Debug) std::clog << "pkgAcqDiffIndex failed: " << Desc.URI << std::endl - << "Falling back to normal index file aquire" << std::endl; + << "Falling back to normal index file acquire" << std::endl; new pkgAcqIndex(Owner, RealURI, Description, Desc.ShortDesc, ExpectedHash); @@ -569,7 +569,7 @@ void pkgAcqDiffIndex::Done(string Message,unsigned long long Size,string Md5Hash string FinalFile; FinalFile = _config->FindDir("Dir::State::lists")+URItoFileName(RealURI); - // sucess in downloading the index + // success in downloading the index // rename the index FinalFile += string(".IndexDiff"); if(Debug) @@ -628,7 +628,7 @@ void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{ { if(Debug) std::clog << "pkgAcqIndexDiffs failed: " << Desc.URI << std::endl - << "Falling back to normal index file aquire" << std::endl; + << "Falling back to normal index file acquire" << std::endl; new pkgAcqIndex(Owner, RealURI, Description,Desc.ShortDesc, ExpectedHash); Finish(); @@ -733,7 +733,7 @@ void pkgAcqIndexDiffs::Done(string Message,unsigned long long Size,string Md5Has string FinalFile; FinalFile = _config->FindDir("Dir::State::lists")+URItoFileName(RealURI); - // sucess in downloading a diff, enter ApplyDiff state + // success in downloading a diff, enter ApplyDiff state if(State == StateFetchDiff) { @@ -825,7 +825,7 @@ void pkgAcqIndexMergeDiffs::Failed(string Message,pkgAcquire::MethodConfig *Cnf) // first failure means we should fallback State = StateErrorDiff; - std::clog << "Falling back to normal index file aquire" << std::endl; + std::clog << "Falling back to normal index file acquire" << std::endl; new pkgAcqIndex(Owner, RealURI, Description,Desc.ShortDesc, ExpectedHash); } @@ -1240,7 +1240,7 @@ pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner, /*{{{*/ if (RealFileExists(Final) == true) { // File was already in place. It needs to be re-downloaded/verified - // because Release might have changed, we do give it a differnt + // because Release might have changed, we do give it a different // name than DestFile because otherwise the http method will // send If-Range requests and there are too many broken servers // out there that do not understand them @@ -2021,7 +2021,7 @@ bool pkgAcqArchive::QueueNext() return true; } - /* Hmm, we have a file and its size does not match, this shouldnt + /* Hmm, we have a file and its size does not match, this shouldn't happen.. */ unlink(FinalFile.c_str()); } diff --git a/apt-pkg/acquire-worker.cc b/apt-pkg/acquire-worker.cc index 44c3e4e17..de62080da 100644 --- a/apt-pkg/acquire-worker.cc +++ b/apt-pkg/acquire-worker.cc @@ -568,7 +568,7 @@ bool pkgAcquire::Worker::InFdReady() /*}}}*/ // Worker::MethodFailure - Called when the method fails /*{{{*/ // --------------------------------------------------------------------- -/* This is called when the method is belived to have failed, probably because +/* This is called when the method is believed to have failed, probably because read returned -1. */ bool pkgAcquire::Worker::MethodFailure() { diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index a8a5abd34..120e809e1 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -5,9 +5,9 @@ Acquire - File Acquiration - The core element for the schedual system is the concept of a named + The core element for the schedule system is the concept of a named queue. Each queue is unique and each queue has a name derived from the - URI. The degree of paralization can be controled by how the queue + URI. The degree of paralization can be controlled by how the queue name is derived from the URI. ##################################################################### */ @@ -175,7 +175,7 @@ void pkgAcquire::Add(Worker *Work) // --------------------------------------------------------------------- /* A worker has died. This can not be done while the select loop is running as it would require that RunFds could handling a changing list state and - it cant.. */ + it can't.. */ void pkgAcquire::Remove(Worker *Work) { if (Running == true) diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 8644a8138..0363ab3e2 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -424,7 +424,7 @@ void pkgProblemResolver::MakeScores() /* This is arbitrary, it should be high enough to elevate an essantial package above most other packages but low enough to allow an obsolete essential packages to be removed by - a conflicts on a powerfull normal package (ie libc6) */ + a conflicts on a powerful normal package (ie libc6) */ if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential || (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) Score += PrioEssentials; @@ -441,7 +441,7 @@ void pkgProblemResolver::MakeScores() Score += PrioInstalledAndNotObsolete; } - // Now that we have the base scores we go and propogate dependencies + // Now that we have the base scores we go and propagate dependencies for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) { if (Cache[I].InstallVer == 0) @@ -485,7 +485,7 @@ void pkgProblemResolver::MakeScores() } } - /* Now we propogate along provides. This makes the packages that + /* Now we propagate along provides. This makes the packages that provide important packages extremely important */ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) { @@ -640,7 +640,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) adjusting the package will inflict. It goes from highest score to lowest and corrects all of the breaks by - keeping or removing the dependant packages. If that fails then it removes + keeping or removing the dependent packages. If that fails then it removes the package itself and goes on. The routine should be able to intelligently go from any broken state to a fixed state. @@ -830,7 +830,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) /* Look across the version list. If there are no possible targets then we keep the package and bail. This is necessary - if a package has a dep on another package that cant be found */ + if a package has a dep on another package that can't be found */ SPtrArray VList = Start.AllTargets(); if (*VList == 0 && (Flags[I->ID] & Protected) != Protected && Start.IsNegative() == false && @@ -1183,7 +1183,7 @@ bool pkgProblemResolver::ResolveByKeepInternal() continue; /* Keep the package. If this works then great, otherwise we have - to be significantly more agressive and manipulate its dependencies */ + to be significantly more aggressive and manipulate its dependencies */ if ((Flags[I->ID] & Protected) == 0) { if (Debug == true) diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h index 5a9a77415..489d81159 100644 --- a/apt-pkg/algorithms.h +++ b/apt-pkg/algorithms.h @@ -10,7 +10,7 @@ see all of the effects of an upgrade run. pkgDistUpgrade computes an upgrade that causes as many packages as - possible to move to the newest verison. + possible to move to the newest version. pkgApplyStatus sets the target state based on the content of the status field in the status file. It is important to get proper crash recovery. @@ -44,7 +44,7 @@ using std::ostream; #endif #ifndef APT_9_CLEANER_HEADERS -// include pkg{DistUpgrade,AllUpgrade,MiniizeUpgrade} here for compatiblity +// include pkg{DistUpgrade,AllUpgrade,MiniizeUpgrade} here for compatibility #include #include #endif diff --git a/apt-pkg/aptconfiguration.cc b/apt-pkg/aptconfiguration.cc index 1ebcf97bc..0b0b546c5 100644 --- a/apt-pkg/aptconfiguration.cc +++ b/apt-pkg/aptconfiguration.cc @@ -27,9 +27,9 @@ #include /*}}}*/ namespace APT { -// getCompressionTypes - Return Vector of usbale compressiontypes /*{{{*/ +// getCompressionTypes - Return Vector of usable compressiontypes /*{{{*/ // --------------------------------------------------------------------- -/* return a vector of compression types in the prefered order. */ +/* return a vector of compression types in the preferred order. */ std::vector const Configuration::getCompressionTypes(bool const &Cached) { static std::vector types; @@ -109,7 +109,7 @@ const Configuration::getCompressionTypes(bool const &Cached) { /*}}}*/ // GetLanguages - Return Vector of Language Codes /*{{{*/ // --------------------------------------------------------------------- -/* return a vector of language codes in the prefered order. +/* return a vector of language codes in the preferred order. the special word "environment" will be replaced with the long and the short code of the local settings and it will be insured that this will not add duplicates. So in an german local the setting "environment, de_DE, en, de" @@ -330,7 +330,7 @@ bool const Configuration::checkLanguage(std::string Lang, bool const All) { return (std::find(langs.begin(), langs.end(), Lang) != langs.end()); } /*}}}*/ -// getArchitectures - Return Vector of prefered Architectures /*{{{*/ +// getArchitectures - Return Vector of preferred Architectures /*{{{*/ std::vector const Configuration::getArchitectures(bool const &Cached) { using std::string; diff --git a/apt-pkg/aptconfiguration.h b/apt-pkg/aptconfiguration.h index d22b675c0..bf7deae85 100644 --- a/apt-pkg/aptconfiguration.h +++ b/apt-pkg/aptconfiguration.h @@ -37,14 +37,14 @@ public: /*{{{*/ * \param Cached saves the result so we need to calculated it only once * this parameter should ony be used for testing purposes. * - * \return a vector of the compression types in the prefered usage order + * \return a vector of the compression types in the preferred usage order */ std::vector static const getCompressionTypes(bool const &Cached = true); /** \brief Returns a vector of Language Codes * * Languages can be defined with their two or five chars long code. - * This methods handles the various ways to set the prefered codes, + * This methods handles the various ways to set the preferred codes, * honors the environment and ensures that the codes are not listed twice. * * The special word "environment" will be replaced with the long and the short @@ -52,7 +52,7 @@ public: /*{{{*/ * duplicates. So in an german local the setting "environment, de_DE, en, de" * will result in "de_DE, de, en". * - * Another special word is "none" which separates the prefered from all codes + * Another special word is "none" which separates the preferred from all codes * in this setting. So setting and method can be used to get codes the user want * to see or to get all language codes APT (should) have Translations available. * @@ -62,7 +62,7 @@ public: /*{{{*/ * \param Locale don't get the locale from the system but use this one instead * this parameter should ony be used for testing purposes. * - * \return a vector of (all) Language Codes in the prefered usage order + * \return a vector of (all) Language Codes in the preferred usage order */ std::vector static const getLanguages(bool const &All = false, bool const &Cached = true, char const ** const Locale = 0); @@ -80,7 +80,7 @@ public: /*{{{*/ * \param Cached saves the result so we need to calculated it only once * this parameter should ony be used for testing purposes. * - * \return a vector of Architectures in prefered order + * \return a vector of Architectures in preferred order */ std::vector static const getArchitectures(bool const &Cached = true); diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index 886d84838..ea6a4afba 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -46,7 +46,7 @@ template class pkgCache::Iterator : * The implementation of this method should be pretty short * as it will only return the Pointer into the mmap stored * in the owner but the name of this pointer is different for - * each stucture and we want to abstract here at least for the + * each structure and we want to abstract here at least for the * basic methods from the actual structure. * \return Pointer to the first structure of this type */ @@ -198,7 +198,7 @@ class pkgCache::VerIterator : public Iterator { /** \brief compares two version and returns if they are similar This method should be used to identify if two pseudo versions are - refering to the same "real" version */ + referring to the same "real" version */ inline bool SimilarVer(const VerIterator &B) const { return (B.end() == false && S->Hash == B->Hash && strcmp(VerStr(), B.VerStr()) == 0); }; @@ -419,7 +419,7 @@ class pkgCache::DescFileIterator : public Iterator { inline DescFileIterator(pkgCache &Owner,DescFile *Trg) : Iterator(Owner, Trg) {}; }; /*}}}*/ -// Inlined Begin functions cant be in the class because of order problems /*{{{*/ +// Inlined Begin functions can't be in the class because of order problems /*{{{*/ inline pkgCache::PkgIterator pkgCache::GrpIterator::PackageList() const {return PkgIterator(*Owner,Owner->PkgP + S->FirstPackage);}; inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const diff --git a/apt-pkg/cdrom.h b/apt-pkg/cdrom.h index db637b96d..c58593550 100644 --- a/apt-pkg/cdrom.h +++ b/apt-pkg/cdrom.h @@ -88,7 +88,7 @@ struct CdromDevice /*{{{*/ class pkgUdevCdromDevices /*{{{*/ { protected: - // libudev dlopen stucture + // libudev dlopen structure void *libudev_handle; struct udev* (*udev_new)(void); int (*udev_enumerate_add_match_property)(struct udev_enumerate *udev_enumerate, const char *property, const char *value); diff --git a/apt-pkg/clean.cc b/apt-pkg/clean.cc index eae419e34..2dea8ffdd 100644 --- a/apt-pkg/clean.cc +++ b/apt-pkg/clean.cc @@ -105,7 +105,7 @@ bool pkgArchiveCleaner::Go(std::string Dir,pkgCache &Cache) break; } - // See if this verison matches the file + // See if this version matches the file if (IsFetchable == true && Ver == V.VerStr()) break; } diff --git a/apt-pkg/contrib/cdromutl.cc b/apt-pkg/contrib/cdromutl.cc index afa01a562..20210ec0a 100644 --- a/apt-pkg/contrib/cdromutl.cc +++ b/apt-pkg/contrib/cdromutl.cc @@ -47,8 +47,8 @@ bool IsMounted(string &Path) if (Path[Path.length() - 1] != '/') Path += '/'; - /* First we check if the path is actualy mounted, we do this by - stating the path and the previous directory (carefull of links!) + /* First we check if the path is actually mounted, we do this by + stating the path and the previous directory (careful of links!) and comparing their device fields. */ struct stat Buf,Buf2; if (stat(Path.c_str(),&Buf) != 0 || diff --git a/apt-pkg/contrib/cmndline.cc b/apt-pkg/contrib/cmndline.cc index 2086d91ca..ed5800007 100644 --- a/apt-pkg/contrib/cmndline.cc +++ b/apt-pkg/contrib/cmndline.cc @@ -293,7 +293,7 @@ bool CommandLine::HandleOpt(int &I,int argc,const char *argv[], // Look for an argument. while (1) { - // Look at preceeding text + // Look at preceding text char Buffer[300]; if (Argument == 0) { diff --git a/apt-pkg/contrib/crc-16.cc b/apt-pkg/contrib/crc-16.cc index 4058821f9..f5df2d8b1 100644 --- a/apt-pkg/contrib/crc-16.cc +++ b/apt-pkg/contrib/crc-16.cc @@ -10,7 +10,7 @@ Al Longyear Modified by Jason Gunthorpe to fit the local coding - style, this code is belived to be in the Public Domain. + style, this code is believed to be in the Public Domain. ##################################################################### */ /*}}}*/ diff --git a/apt-pkg/contrib/error.h b/apt-pkg/contrib/error.h index 7d09b2d4a..bcee70b1a 100644 --- a/apt-pkg/contrib/error.h +++ b/apt-pkg/contrib/error.h @@ -229,7 +229,7 @@ public: /*{{{*/ /** \brief is the list empty? * * The default checks if the list is empty or contains only notices, - * if you want to check if also no notices happend set the parameter + * if you want to check if also no notices happened set the parameter * flag to \b false. * * \param WithoutNotice does notices count, default is \b true, so no diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 536284064..52411a762 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -222,7 +222,7 @@ int GetLock(string File,bool Errors) int FD = open(File.c_str(),O_RDWR | O_CREAT | O_NOFOLLOW,0640); if (FD < 0) { - // Read only .. cant have locking problems there. + // Read only .. can't have locking problems there. if (errno == EROFS) { _error->Warning(_("Not using locking for read only lock file %s"),File.c_str()); @@ -238,7 +238,7 @@ int GetLock(string File,bool Errors) } SetCloseExec(FD,true); - // Aquire a write lock + // Acquire a write lock struct flock fl; fl.l_type = F_WRLCK; fl.l_whence = SEEK_SET; @@ -1256,7 +1256,7 @@ FileFd::~FileFd() /*}}}*/ // FileFd::Read - Read a bit of the file /*{{{*/ // --------------------------------------------------------------------- -/* We are carefull to handle interruption by a signal while reading +/* We are careful to handle interruption by a signal while reading gracefully. */ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual) { diff --git a/apt-pkg/contrib/gpgv.h b/apt-pkg/contrib/gpgv.h index 45f069058..1d79a52ac 100644 --- a/apt-pkg/contrib/gpgv.h +++ b/apt-pkg/contrib/gpgv.h @@ -29,7 +29,7 @@ * for reading. Use #OpenMaybeClearSignedFile to access the message * instead to ensure you are only reading signed data. * - * The method does not return, but has some noteable exit-codes: + * The method does not return, but has some notable exit-codes: * 111 signals an internal error like the inability to execute gpgv, * 112 indicates a clear-signed file which doesn't include a message, * which can happen if APT is run while on a network requiring diff --git a/apt-pkg/contrib/macros.h b/apt-pkg/contrib/macros.h index 62e7b65db..e53d01b8f 100644 --- a/apt-pkg/contrib/macros.h +++ b/apt-pkg/contrib/macros.h @@ -44,7 +44,7 @@ #define _boundv(a,b,c) b = _bound(a,b,c) #define ABS(a) (((a) < (0)) ?-(a) : (a)) -/* Usefull count macro, use on an array of things and it will return the +/* Useful count macro, use on an array of things and it will return the number of items in the array */ #define _count(a) (sizeof(a)/sizeof(a[0])) diff --git a/apt-pkg/contrib/md5.h b/apt-pkg/contrib/md5.h index 25631b166..195455645 100644 --- a/apt-pkg/contrib/md5.h +++ b/apt-pkg/contrib/md5.h @@ -10,7 +10,7 @@ store a MD5Sum in 16 bytes of memory. A MD5Sum is used to generate a (hopefully) unique 16 byte number for a - block of data. This can be used to gaurd against corruption of a file. + block of data. This can be used to guard against corruption of a file. MD5 should not be used for tamper protection, use SHA or something more secure. diff --git a/apt-pkg/contrib/mmap.h b/apt-pkg/contrib/mmap.h index 6bd4a2d86..c1dfedf6d 100644 --- a/apt-pkg/contrib/mmap.h +++ b/apt-pkg/contrib/mmap.h @@ -6,7 +6,7 @@ MMap Class - Provides 'real' mmap or a faked mmap using read(). The purpose of this code is to provide a generic way for clients to - access the mmap function. In enviroments that do not support mmap + access the mmap function. In environments that do not support mmap from file fd's this function will use read and normal allocated memory. @@ -15,7 +15,7 @@ The DynamicMMap class is used to help the on-disk data structure generators. It provides a large allocated workspace and members - to allocate space from the workspace in an effecient fashion. + to allocate space from the workspace in an efficient fashion. This source is placed in the Public Domain, do with it what you will It was originally written by Jason Gunthorpe. diff --git a/apt-pkg/contrib/progress.h b/apt-pkg/contrib/progress.h index 3a6943aee..f7fbc9ccf 100644 --- a/apt-pkg/contrib/progress.h +++ b/apt-pkg/contrib/progress.h @@ -7,7 +7,7 @@ This class allows lengthy operations to communicate their progress to the GUI. The progress model is simple and is not designed to handle - the complex case of the multi-activity aquire class. + the complex case of the multi-activity acquire class. The model is based on the concept of an overall operation consisting of a series of small sub operations. Each sub operation has it's own diff --git a/apt-pkg/contrib/sha2_internal.cc b/apt-pkg/contrib/sha2_internal.cc index f84fb761c..bb2560252 100644 --- a/apt-pkg/contrib/sha2_internal.cc +++ b/apt-pkg/contrib/sha2_internal.cc @@ -65,7 +65,7 @@ * Please make sure that your system defines BYTE_ORDER. If your * architecture is little-endian, make sure it also defines * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are - * equivilent. + * equivalent. * * If your system does not define the above, then you can do so by * hand like this: diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index 962112854..d4f53ea3a 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -426,7 +426,7 @@ string TimeToStr(unsigned long Sec) /*}}}*/ // SubstVar - Substitute a string for another string /*{{{*/ // --------------------------------------------------------------------- -/* This replaces all occurances of Subst with Contents in Str. */ +/* This replaces all occurrences of Subst with Contents in Str. */ string SubstVar(const string &Str,const string &Subst,const string &Contents) { string::size_type Pos = 0; @@ -926,7 +926,7 @@ bool FTPMDTMStrToTime(const char* const str,time_t &time) /*}}}*/ // StrToTime - Converts a string into a time_t /*{{{*/ // --------------------------------------------------------------------- -/* This handles all 3 populare time formats including RFC 1123, RFC 1036 +/* This handles all 3 popular time formats including RFC 1123, RFC 1036 and the C library asctime format. It requires the GNU library function 'timegm' to convert a struct tm in UTC to a time_t. For some bizzar reason the C library does not provide any such function :< This also @@ -1313,7 +1313,7 @@ string StripEpoch(const string &VerStr) // tolower_ascii - tolower() function that ignores the locale /*{{{*/ // --------------------------------------------------------------------- /* This little function is the most called method we have and tries - therefore to do the absolut minimum - and is noteable faster than + therefore to do the absolut minimum - and is notable faster than standard tolower/toupper and as a bonus avoids problems with different locales - we only operate on ascii chars anyway. */ int tolower_ascii(int const c) @@ -1324,9 +1324,9 @@ int tolower_ascii(int const c) } /*}}}*/ -// CheckDomainList - See if Host is in a , seperate list /*{{{*/ +// CheckDomainList - See if Host is in a , separate list /*{{{*/ // --------------------------------------------------------------------- -/* The domain list is a comma seperate list of domains that are suffix +/* The domain list is a comma separate list of domains that are suffix matched against the argument */ bool CheckDomainList(const string &Host,const string &List) { diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 68d544e1f..acdcc4554 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -758,7 +758,7 @@ bool debListParser::GrabWord(string Word,WordList *List,unsigned char &Out) /*}}}*/ // ListParser::Step - Move to the next section in the file /*{{{*/ // --------------------------------------------------------------------- -/* This has to be carefull to only process the correct architecture */ +/* This has to be careful to only process the correct architecture */ bool debListParser::Step() { iOffset = Tags.Offset(); diff --git a/apt-pkg/deb/debsystem.cc b/apt-pkg/deb/debsystem.cc index 7ed6936c3..b95ff15df 100644 --- a/apt-pkg/deb/debsystem.cc +++ b/apt-pkg/deb/debsystem.cc @@ -193,7 +193,7 @@ bool debSystem::Initialize(Configuration &Cnf) /*}}}*/ // System::ArchiveSupported - Is a file format supported /*{{{*/ // --------------------------------------------------------------------- -/* The standard name for a deb is 'deb'.. There are no seperate versions +/* The standard name for a deb is 'deb'.. There are no separate versions of .deb to worry about.. */ bool debSystem::ArchiveSupported(const char *Type) { diff --git a/apt-pkg/deb/debversion.cc b/apt-pkg/deb/debversion.cc index 140561262..74e2552ff 100644 --- a/apt-pkg/deb/debversion.cc +++ b/apt-pkg/deb/debversion.cc @@ -116,7 +116,7 @@ int debVersioningSystem::CmpFragment(const char *A,const char *AEnd, return 1; } - // Shouldnt happen + // Shouldn't happen return 1; } /*}}}*/ @@ -221,7 +221,7 @@ bool debVersioningSystem::CheckDep(const char *PkgVer, if (PkgVer == DepVer) return Op == pkgCache::Dep::Equals || Op == pkgCache::Dep::LessEq || Op == pkgCache::Dep::GreaterEq; - // Perform the actual comparision. + // Perform the actual comparison. int const Res = CmpVersion(PkgVer, DepVer); switch (Op) { diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index c39e8c628..a12e6963d 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -789,7 +789,7 @@ bool pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser, // - this makes sense as default when all Garbage dependencies // are automatically marked for removal (as aptitude does). // setting a package for keep then makes it no longer autoinstalled - // for all other use-case this action is rather suprising + // for all other use-case this action is rather surprising if(FromUser && !P.Marked) P.Flags &= ~Flag::Auto; #endif @@ -1195,7 +1195,7 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, } } - /* This bit is for processing the possibilty of an install/upgrade + /* This bit is for processing the possibility of an install/upgrade fixing the problem for "positive" dependencies */ if (Start.IsNegative() == false && (DepState[Start->ID] & DepCVer) == DepCVer) { @@ -1315,7 +1315,7 @@ bool pkgDepCache::IsInstallOkMultiArchSameVersionSynced(PkgIterator const &Pkg, // (simple string-compare as stuff like '1' == '0:1-0' can't happen here) if (P->CurrentVer == 0 || strcmp(Pkg.CandVersion(), P.CandVersion()) == 0) continue; - // packages loosing M-A:same can be out-of-sync + // packages losing M-A:same can be out-of-sync VerIterator CV = PkgState[P->ID].CandidateVerIter(*this); if (unlikely(CV.end() == true) || (CV->MultiArch & pkgCache::Version::Same) != pkgCache::Version::Same) diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index 61c9aa559..f6848f383 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -15,7 +15,7 @@ This structure is important to support the readonly status of the cache file. When the data is saved the cache will be refereshed from our - internal rep and written to disk. Then the actual persistant data + internal rep and written to disk. Then the actual persistent data files will be put on the disk. Each dependency is compared against 3 target versions to produce to diff --git a/apt-pkg/edsp.h b/apt-pkg/edsp.h index 12b06d143..fd4436f60 100644 --- a/apt-pkg/edsp.h +++ b/apt-pkg/edsp.h @@ -2,7 +2,7 @@ /** Description \file edsp.h {{{ ###################################################################### Set of methods to help writing and reading everything needed for EDSP - with the noteable exception of reading a scenario for conversion into + with the notable exception of reading a scenario for conversion into a Cache as this is handled by edsp interface for listparser and friends ##################################################################### */ /*}}}*/ @@ -182,13 +182,13 @@ public: * they were unable to calculate a solution for a given task. * Obviously they can't send a solution through, so this * methods deals with formatting an error message correctly - * so that the front-ends can recieve and display it. + * so that the front-ends can receive and display it. * * The first line of the message should be a short description * of the error so it can be used for dialog titles or alike * * \param uuid of this error message - * \param message is free form text to discribe the error + * \param message is free form text to describe the error * \param output the front-end listens for error messages */ bool static WriteError(char const * const uuid, std::string const &message, FILE* output); diff --git a/apt-pkg/indexfile.h b/apt-pkg/indexfile.h index 2d433b60a..a0096fa34 100644 --- a/apt-pkg/indexfile.h +++ b/apt-pkg/indexfile.h @@ -10,12 +10,12 @@ Binary index files Binary translation files - Bianry index files decribing the local system + Binary index files describing the local system Source index files They are all bundled together here, and the interfaces for sources.list, acquire, cache gen and record parsing all use this class - to acess the underlying representation. + to access the underlying representation. ##################################################################### */ /*}}}*/ diff --git a/apt-pkg/orderlist.cc b/apt-pkg/orderlist.cc index 984ae1d10..21b5fc4e7 100644 --- a/apt-pkg/orderlist.cc +++ b/apt-pkg/orderlist.cc @@ -566,10 +566,10 @@ bool pkgOrderList::VisitProvides(DepIterator D,bool Critical) // --------------------------------------------------------------------- /* 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. */ + depth is achieved through the colouring mechinism. */ bool pkgOrderList::VisitNode(PkgIterator Pkg, char const* from) { - // Looping or irrelevent. + // Looping or irrelevant. // This should probably trancend not installed packages if (Pkg.end() == true || IsFlag(Pkg,Added) == true || IsFlag(Pkg,AddPending) == true || IsFlag(Pkg,InList) == false) @@ -824,7 +824,7 @@ bool pkgOrderList::DepUnPackPre(DepIterator D) The forwards depends loop is designed to bring the packages dependents close to the package. This helps reduce deconfigure time. - Loops are irrelevent to this. */ + Loops are irrelevant to this. */ bool pkgOrderList::DepUnPackDep(DepIterator D) { @@ -840,7 +840,7 @@ bool pkgOrderList::DepUnPackDep(DepIterator D) D.ParentPkg().CurrentVer() != D.ParentVer()) continue; - // The dep will not break so it is irrelevent. + // The dep will not break so it is irrelevant. if (CheckDep(D) == true) continue; diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index 3fdd9b637..5f9a31264 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -215,7 +215,7 @@ bool pkgPackageManager::CreateOrderList() return true; } /*}}}*/ -// PM::DepAlwaysTrue - Returns true if this dep is irrelevent /*{{{*/ +// PM::DepAlwaysTrue - Returns true if this dep is irrelevant /*{{{*/ // --------------------------------------------------------------------- /* The restriction on provides is to eliminate the case when provides are transitioning between valid states [ie exim to smail] */ @@ -243,11 +243,11 @@ bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg,DepIterator D, D->Type != pkgCache::Dep::Obsoletes) continue; - // The package hasnt been changed + // The package hasn't been changed if (List->IsNow(Pkg) == false) continue; - // Ignore self conflicts, ignore conflicts from irrelevent versions + // Ignore self conflicts, ignore conflicts from irrelevant versions if (D.IsIgnorable(Pkg) || D.ParentVer() != D.ParentPkg().CurrentVer()) continue; @@ -314,7 +314,7 @@ bool pkgPackageManager::ConfigureAll() 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 + SmartConfigure, it may fail because of a complex dependency 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*/ @@ -596,7 +596,7 @@ bool pkgPackageManager::SmartRemove(PkgIterator Pkg) /*}}}*/ // PM::SmartUnPack - Install helper /*{{{*/ // --------------------------------------------------------------------- -/* This puts the system in a state where it can Unpack Pkg, if Pkg is allready +/* This puts the system in a state where it can Unpack Pkg, if Pkg is already unpacked, or when it has been unpacked, if Immediate==true it configures it. */ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) { @@ -623,7 +623,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c /* 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 . + complex dependency 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. */ bool Changed = false; @@ -790,7 +790,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c { if (List->IsFlag(BrokenPkg,pkgOrderList::Loop) && PkgLoop) { - // This dependancy has already been dealt with by another SmartUnPack on Pkg + // This dependency has already been dealt with by another SmartUnPack on Pkg break; } else @@ -1003,7 +1003,7 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() DoneSomething = true; if (ImmConfigureAll) { - /* ConfigureAll here to pick up and packages left unconfigured becuase they were unpacked in the + /* ConfigureAll here to pick up and packages left unconfigured because they were unpacked in the "PreUnpack Checks" section */ if (!ConfigureAll()) return Failed; diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 52e814c0b..67a2a709d 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -8,7 +8,7 @@ Please see doc/apt-pkg/cache.sgml for a more detailed description of this format. Also be sure to keep that file up-to-date!! - This is the general utility functions for cache managment. They provide + This is the general utility functions for cache management. They provide a complete set of accessor functions for the cache. The cacheiterators header contains the STL-like iterators that can be used to easially navigate the cache as well as seemlessly dereference the mmap'd @@ -499,7 +499,7 @@ pkgCache::PkgIterator::CurVersion() const // ostream operator to handle string representation of a package /*{{{*/ // --------------------------------------------------------------------- /* Output name < cur.rent.version -> candid.ate.version | new.est.version > (section) - Note that the characters <|>() are all literal above. Versions will be ommited + Note that the characters <|>() are all literal above. Versions will be omitted if they provide no new information (e.g. there is no newer version than candidate) If no version and/or section can be found "none" is used. */ std::ostream& diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index 1a7013551..c31c5f30b 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -354,7 +354,7 @@ struct pkgCache::Group the hash index of the name in the pkgCache::Header::PkgHashTable A package can be created for every architecture so package names are - not unique, but it is garanteed that packages with the same name + not unique, but it is guaranteed that packages with the same name are sequencel ordered in the list. Packages with the same name can be accessed with the Group. */ diff --git a/apt-pkg/pkgsystem.h b/apt-pkg/pkgsystem.h index 75f7b9fcc..eb75df412 100644 --- a/apt-pkg/pkgsystem.h +++ b/apt-pkg/pkgsystem.h @@ -7,7 +7,7 @@ Instances of this class can be thought of as factories or meta-classes for a variety of more specialized classes. Together this class and - it's speciallized offspring completely define the environment and how + it's specialized offspring completely define the environment and how to access resources for a specific system. There are several sub areas that are all orthogonal - each system has a unique combination of these sub areas: @@ -23,7 +23,7 @@ - Selection of local 'status' indexes that make up the pkgCache. It is important to note that the handling of index files is not a - function of the system. Index files are handled through a seperate + function of the system. Index files are handled through a separate abstraction - the only requirement is that the index files have the same idea of versioning as the target system. diff --git a/apt-pkg/upgrade.cc b/apt-pkg/upgrade.cc index f06f6d40d..d6f6933dd 100644 --- a/apt-pkg/upgrade.cc +++ b/apt-pkg/upgrade.cc @@ -225,7 +225,7 @@ bool pkgMinimizeUpgrade(pkgDepCache &Cache) Cache.MarkInstall(I, false, 0, false); else { - // If keep didnt actually do anything then there was no change.. + // If keep didn't actually do anything then there was no change.. if (Cache[I].Upgrade() == false) Change = true; } -- cgit v1.2.3