diff -Nru apt-1.0.9.3ubuntu1/apt-pkg/algorithms.cc apt-1.0.9.7ubuntu3/apt-pkg/algorithms.cc --- apt-1.0.9.3ubuntu1/apt-pkg/algorithms.cc 2014-11-03 07:59:35.000000000 +0000 +++ apt-1.0.9.7ubuntu3/apt-pkg/algorithms.cc 2015-03-23 07:59:06.000000000 +0000 @@ -468,7 +468,7 @@ if (D->Version != 0) { pkgCache::VerIterator const IV = Cache[T].InstVerIter(Cache); - if (IV.end() == true || D.IsSatisfied(IV) != D.IsNegative()) + if (IV.end() == true || D.IsSatisfied(IV) == false) continue; } Scores[T->ID] += DepMap[D->Type]; diff -Nru apt-1.0.9.3ubuntu1/apt-pkg/cacheiterators.h apt-1.0.9.7ubuntu3/apt-pkg/cacheiterators.h --- apt-1.0.9.3ubuntu1/apt-pkg/cacheiterators.h 2014-11-03 07:59:35.000000000 +0000 +++ apt-1.0.9.7ubuntu3/apt-pkg/cacheiterators.h 2015-03-23 07:59:06.000000000 +0000 @@ -160,7 +160,9 @@ // Accessors inline const char *Name() const {return S->Name == 0?0:Owner->StrP + S->Name;} - inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;} + // Versions have sections - and packages can have different versions with different sections + // so this interface is broken by design. Run as fast as you can to Version.Section(). + APT_DEPRECATED inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;} inline bool Purge() const {return S->CurrentState == pkgCache::State::Purge || (S->CurrentVer == 0 && S->CurrentState == pkgCache::State::NotInstalled);} inline const char *Arch() const {return S->Arch == 0?0:Owner->StrP + S->Arch;} diff -Nru apt-1.0.9.3ubuntu1/apt-pkg/cacheset.h apt-1.0.9.7ubuntu3/apt-pkg/cacheset.h --- apt-1.0.9.3ubuntu1/apt-pkg/cacheset.h 2014-11-03 07:59:35.000000000 +0000 +++ apt-1.0.9.7ubuntu3/apt-pkg/cacheset.h 2015-03-23 07:59:06.000000000 +0000 @@ -118,7 +118,16 @@ inline const char *Name() const {return getPkg().Name(); } inline std::string FullName(bool const Pretty) const { return getPkg().FullName(Pretty); } inline std::string FullName() const { return getPkg().FullName(); } - inline const char *Section() const {return getPkg().Section(); } + APT_DEPRECATED inline const char *Section() const { +#if __GNUC__ >= 4 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + return getPkg().Section(); +#if __GNUC__ >= 4 + #pragma GCC diagnostic pop +#endif + } inline bool Purge() const {return getPkg().Purge(); } inline const char *Arch() const {return getPkg().Arch(); } inline pkgCache::GrpIterator Group() const { return getPkg().Group(); } diff -Nru apt-1.0.9.3ubuntu1/apt-pkg/contrib/cmndline.cc apt-1.0.9.7ubuntu3/apt-pkg/contrib/cmndline.cc --- apt-1.0.9.3ubuntu1/apt-pkg/contrib/cmndline.cc 2014-11-03 07:59:35.000000000 +0000 +++ apt-1.0.9.7ubuntu3/apt-pkg/contrib/cmndline.cc 2015-03-23 07:59:06.000000000 +0000 @@ -47,23 +47,26 @@ char const * CommandLine::GetCommand(Dispatch const * const Map, unsigned int const argc, char const * const * const argv) { - // if there is a -- on the line there must be the word we search for around it - // as -- marks the end of the options, just not sure if the command can be - // considered an option or not, so accept both + // if there is a -- on the line there must be the word we search for either + // before it (as -- marks the end of the options) or right after it (as we can't + // decide if the command is actually an option, given that in theory, you could + // have parameters named like commands) for (size_t i = 1; i < argc; ++i) { if (strcmp(argv[i], "--") != 0) continue; - ++i; - if (i < argc) + // check if command is before -- + for (size_t k = 1; k < i; ++k) for (size_t j = 0; Map[j].Match != NULL; ++j) - if (strcmp(argv[i], Map[j].Match) == 0) + if (strcmp(argv[k], Map[j].Match) == 0) return Map[j].Match; - i -= 2; - if (i != 0) + // see if the next token after -- is the command + ++i; + if (i < argc) for (size_t j = 0; Map[j].Match != NULL; ++j) if (strcmp(argv[i], Map[j].Match) == 0) return Map[j].Match; + // we found a --, but not a command return NULL; } // no --, so search for the first word matching a command diff -Nru apt-1.0.9.3ubuntu1/apt-pkg/contrib/hashes.cc apt-1.0.9.7ubuntu3/apt-pkg/contrib/hashes.cc --- apt-1.0.9.3ubuntu1/apt-pkg/contrib/hashes.cc 2014-11-03 07:59:35.000000000 +0000 +++ apt-1.0.9.7ubuntu3/apt-pkg/contrib/hashes.cc 2015-03-23 07:59:06.000000000 +0000 @@ -27,7 +27,7 @@ #include /*}}}*/ -const char* HashString::_SupportedHashes[] = +const char * HashString::_SupportedHashes[] = { "SHA512", "SHA256", "SHA1", "MD5Sum", NULL }; @@ -42,11 +42,16 @@ HashString::HashString(std::string StringedHash) /*{{{*/ { - // legacy: md5sum without "MD5Sum:" prefix - if (StringedHash.find(":") == std::string::npos && StringedHash.size() == 32) + if (StringedHash.find(":") == std::string::npos) { - Type = "MD5Sum"; - Hash = StringedHash; + // legacy: md5sum without "MD5Sum:" prefix + if (StringedHash.size() == 32) + { + Type = "MD5Sum"; + Hash = StringedHash; + } + if(_config->FindB("Debug::Hashes",false) == true) + std::clog << "HashString(string): invalid StringedHash " << StringedHash << std::endl; return; } std::string::size_type pos = StringedHash.find(":"); @@ -82,25 +87,25 @@ std::string fileHash; FileFd Fd(filename, FileFd::ReadOnly); - if(Type == "MD5Sum") + if(strcasecmp(Type.c_str(), "MD5Sum") == 0) { MD5Summation MD5; MD5.AddFD(Fd); fileHash = (std::string)MD5.Result(); } - else if (Type == "SHA1") + else if (strcasecmp(Type.c_str(), "SHA1") == 0) { SHA1Summation SHA1; SHA1.AddFD(Fd); fileHash = (std::string)SHA1.Result(); } - else if (Type == "SHA256") + else if (strcasecmp(Type.c_str(), "SHA256") == 0) { SHA256Summation SHA256; SHA256.AddFD(Fd); fileHash = (std::string)SHA256.Result(); } - else if (Type == "SHA512") + else if (strcasecmp(Type.c_str(), "SHA512") == 0) { SHA512Summation SHA512; SHA512.AddFD(Fd); @@ -111,20 +116,105 @@ return fileHash; } /*}}}*/ -const char** HashString::SupportedHashes() +const char** HashString::SupportedHashes() /*{{{*/ { return _SupportedHashes; } - -APT_PURE bool HashString::empty() const + /*}}}*/ +APT_PURE bool HashString::empty() const /*{{{*/ { return (Type.empty() || Hash.empty()); } + /*}}}*/ +std::string HashString::toStr() const /*{{{*/ +{ + return Type + ":" + Hash; +} + /*}}}*/ +APT_PURE bool HashString::operator==(HashString const &other) const /*{{{*/ +{ + return (strcasecmp(Type.c_str(), other.Type.c_str()) == 0 && Hash == other.Hash); +} +APT_PURE bool HashString::operator!=(HashString const &other) const +{ + return !(*this == other); +} + /*}}}*/ + +HashString const * HashStringList::find(char const * const type) const /*{{{*/ +{ + if (type == NULL || type[0] == '\0') + { + std::string forcedType = _config->Find("Acquire::ForceHash", ""); + if (forcedType.empty() == false) + return find(forcedType.c_str()); + for (char const * const * t = HashString::SupportedHashes(); *t != NULL; ++t) + for (std::vector::const_iterator hs = list.begin(); hs != list.end(); ++hs) + if (strcasecmp(hs->HashType().c_str(), *t) == 0) + return &*hs; + return NULL; + } + for (std::vector::const_iterator hs = list.begin(); hs != list.end(); ++hs) + if (strcasecmp(hs->HashType().c_str(), type) == 0) + return &*hs; + return NULL; +} + /*}}}*/ +bool HashStringList::supported(char const * const type) /*{{{*/ +{ + for (char const * const * t = HashString::SupportedHashes(); *t != NULL; ++t) + if (strcasecmp(*t, type) == 0) + return true; + return false; +} + /*}}}*/ +bool HashStringList::push_back(const HashString &hashString) /*{{{*/ +{ + if (hashString.HashType().empty() == true || + hashString.HashValue().empty() == true || + supported(hashString.HashType().c_str()) == false) + return false; + + // ensure that each type is added only once + HashString const * const hs = find(hashString.HashType().c_str()); + if (hs != NULL) + return *hs == hashString; -std::string HashString::toStr() const + list.push_back(hashString); + return true; +} + /*}}}*/ +bool HashStringList::VerifyFile(std::string filename) const /*{{{*/ { - return Type + std::string(":") + Hash; + if (list.empty() == true) + return false; + HashString const * const hs = find(NULL); + if (hs == NULL || hs->VerifyFile(filename) == false) + return false; + return true; } + /*}}}*/ +bool HashStringList::operator==(HashStringList const &other) const /*{{{*/ +{ + short matches = 0; + for (const_iterator hs = begin(); hs != end(); ++hs) + { + HashString const * const ohs = other.find(hs->HashType()); + if (ohs == NULL) + continue; + if (*hs != *ohs) + return false; + ++matches; + } + if (matches == 0) + return false; + return true; +} +bool HashStringList::operator!=(HashStringList const &other) const +{ + return !(*this == other); +} + /*}}}*/ // Hashes::AddFD - Add the contents of the FD /*{{{*/ // --------------------------------------------------------------------- diff -Nru apt-1.0.9.3ubuntu1/apt-pkg/contrib/hashes.h apt-1.0.9.7ubuntu3/apt-pkg/contrib/hashes.h --- apt-1.0.9.3ubuntu1/apt-pkg/contrib/hashes.h 2014-11-03 07:59:35.000000000 +0000 +++ apt-1.0.9.7ubuntu3/apt-pkg/contrib/hashes.h 2015-03-23 07:59:06.000000000 +0000 @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -41,7 +42,7 @@ 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; @@ -53,6 +54,8 @@ // get hash type used std::string HashType() { return Type; }; + std::string HashType() const { return Type; }; + std::string HashValue() const { return Hash; }; // verify the given filename against the currently loaded hash bool VerifyFile(std::string filename) const; @@ -64,11 +67,90 @@ // helper std::string toStr() const; // convert to str as "type:hash" bool empty() const; + bool operator==(HashString const &other) const; + bool operator!=(HashString const &other) const; // return the list of hashes we support static APT_CONST const char** SupportedHashes(); }; +class HashStringList +{ + public: + /** find best hash if no specific one is requested + * + * @param type of the checksum to return, can be \b NULL + * @return If type is \b NULL (or the empty string) it will + * return the 'best' hash; otherwise the hash which was + * specifically requested. If no hash is found \b NULL will be returned. + */ + HashString const * find(char const * const type) const; + HashString const * find(std::string const &type) const { return find(type.c_str()); } + /** check if the given hash type is supported + * + * @param type to check + * @return true if supported, otherwise false + */ + static APT_PURE bool supported(char const * const type); + /** add the given #HashString to the list + * + * @param hashString to add + * @return true if the hash is added because it is supported and + * not already a different hash of the same type included, otherwise false + */ + bool push_back(const HashString &hashString); + /** @return size of the list of HashStrings */ + size_t size() const { return list.size(); } + + /** take the 'best' hash and verify file with it + * + * @param filename to verify + * @return true if the file matches the hashsum, otherwise false + */ + bool VerifyFile(std::string filename) const; + + /** is the list empty ? + * + * @return \b true if the list is empty, otherwise \b false + */ + bool empty() const { return list.empty(); } + + typedef std::vector::const_iterator const_iterator; + + /** iterator to the first element */ + const_iterator begin() const { return list.begin(); } + + /** iterator to the end element */ + const_iterator end() const { return list.end(); } + + /** start fresh with a clear list */ + void clear() { list.clear(); } + + /** compare two HashStringList for similarity. + * + * Two lists are similar if at least one hashtype is in both lists + * and the hashsum matches. All hashes are checked, if one doesn't + * match false is returned regardless of how many matched before. + */ + bool operator==(HashStringList const &other) const; + bool operator!=(HashStringList const &other) const; + + HashStringList() {} + + // simplifying API-compatibility constructors + HashStringList(std::string const &hash) { + if (hash.empty() == false) + list.push_back(HashString(hash)); + } + HashStringList(char const * const hash) { + if (hash != NULL && hash[0] != '\0') + list.push_back(HashString(hash)); + } + + private: + std::vector list; +}; + class Hashes { public: diff -Nru apt-1.0.9.3ubuntu1/apt-pkg/deb/debsrcrecords.cc apt-1.0.9.7ubuntu3/apt-pkg/deb/debsrcrecords.cc --- apt-1.0.9.3ubuntu1/apt-pkg/deb/debsrcrecords.cc 2014-11-03 07:59:35.000000000 +0000 +++ apt-1.0.9.7ubuntu3/apt-pkg/deb/debsrcrecords.cc 2015-03-23 07:59:06.000000000 +0000 @@ -118,13 +118,32 @@ // --------------------------------------------------------------------- /* This parses the list of files and returns it, each file is required to have a complete source package */ -bool debSrcRecordParser::Files(std::vector &List) +bool debSrcRecordParser::Files(std::vector &F) { - List.erase(List.begin(),List.end()); - - string Files = Sect.FindS("Files"); - if (Files.empty() == true) + std::vector F2; + if (Files2(F2) == false) return false; + for (std::vector::const_iterator f2 = F2.begin(); f2 != F2.end(); ++f2) + { + pkgSrcRecords::File2 f; +#if __GNUC__ >= 4 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + f.MD5Hash = f2->MD5Hash; + f.Size = f2->Size; +#if __GNUC__ >= 4 + #pragma GCC diagnostic pop +#endif + f.Path = f2->Path; + f.Type = f2->Type; + F.push_back(f); + } + return true; +} +bool debSrcRecordParser::Files2(std::vector &List) +{ + List.clear(); // Stash the / terminated directory prefix string Base = Sect.FindS("Directory"); @@ -133,51 +152,106 @@ std::vector const compExts = APT::Configuration::getCompressorExtensions(); - // Iterate over the entire list grabbing each triplet - const char *C = Files.c_str(); - while (*C != 0) - { - pkgSrcRecords::File F; - string Size; - - // Parse each of the elements - if (ParseQuoteWord(C,F.MD5Hash) == false || - ParseQuoteWord(C,Size) == false || - ParseQuoteWord(C,F.Path) == false) - return _error->Error("Error parsing file record"); - - // Parse the size and append the directory - F.Size = atoi(Size.c_str()); - F.Path = Base + F.Path; - - // Try to guess what sort of file it is we are getting. - string::size_type Pos = F.Path.length()-1; - while (1) + for (char const * const * type = HashString::SupportedHashes(); *type != NULL; ++type) + { + // derive field from checksum type + std::string checksumField("Checksums-"); + if (strcmp(*type, "MD5Sum") == 0) + checksumField = "Files"; // historic name for MD5 checksums + else + checksumField.append(*type); + + string const Files = Sect.FindS(checksumField.c_str()); + if (Files.empty() == true) + continue; + + // Iterate over the entire list grabbing each triplet + const char *C = Files.c_str(); + while (*C != 0) { - string::size_type Tmp = F.Path.rfind('.',Pos); - if (Tmp == string::npos) - break; - if (F.Type == "tar") { - // source v3 has extension 'debian.tar.*' instead of 'diff.*' - if (string(F.Path, Tmp+1, Pos-Tmp) == "debian") - F.Type = "diff"; - break; - } - F.Type = string(F.Path,Tmp+1,Pos-Tmp); - - if (std::find(compExts.begin(), compExts.end(), std::string(".").append(F.Type)) != compExts.end() || - F.Type == "tar") + string hash, size, path; + + // Parse each of the elements + if (ParseQuoteWord(C, hash) == false || + ParseQuoteWord(C, size) == false || + ParseQuoteWord(C, path) == false) + return _error->Error("Error parsing file record in %s of source package %s", checksumField.c_str(), Package().c_str()); + + HashString const hashString(*type, hash); + if (Base.empty() == false) + path = Base + path; + + // look if we have a record for this file already + std::vector::iterator file = List.begin(); + for (; file != List.end(); ++file) + if (file->Path == path) + break; + + // we have it already, store the new hash and be done + if (file != List.end()) { - Pos = Tmp-1; +#if __GNUC__ >= 4 + // set for compatibility only, so warn users not us + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + if (checksumField == "Files") + file->MD5Hash = hash; +#if __GNUC__ >= 4 + #pragma GCC diagnostic pop +#endif + // an error here indicates that we have two different hashes for the same file + if (file->Hashes.push_back(hashString) == false) + return _error->Error("Error parsing checksum in %s of source package %s", checksumField.c_str(), Package().c_str()); continue; } - - break; + + // we haven't seen this file yet + pkgSrcRecords::File2 F; + F.Path = path; + F.FileSize = strtoull(size.c_str(), NULL, 10); + F.Hashes.push_back(hashString); + +#if __GNUC__ >= 4 + // set for compatibility only, so warn users not us + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + F.Size = F.FileSize; + if (checksumField == "Files") + F.MD5Hash = hash; +#if __GNUC__ >= 4 + #pragma GCC diagnostic pop +#endif + + // Try to guess what sort of file it is we are getting. + string::size_type Pos = F.Path.length()-1; + while (1) + { + string::size_type Tmp = F.Path.rfind('.',Pos); + if (Tmp == string::npos) + break; + if (F.Type == "tar") { + // source v3 has extension 'debian.tar.*' instead of 'diff.*' + if (string(F.Path, Tmp+1, Pos-Tmp) == "debian") + F.Type = "diff"; + break; + } + F.Type = string(F.Path,Tmp+1,Pos-Tmp); + + if (std::find(compExts.begin(), compExts.end(), std::string(".").append(F.Type)) != compExts.end() || + F.Type == "tar") + { + Pos = Tmp-1; + continue; + } + + break; + } + List.push_back(F); } - - List.push_back(F); } - + return true; } /*}}}*/ diff -Nru apt-1.0.9.3ubuntu1/apt-pkg/deb/debsrcrecords.h apt-1.0.9.7ubuntu3/apt-pkg/deb/debsrcrecords.h --- apt-1.0.9.3ubuntu1/apt-pkg/deb/debsrcrecords.h 2014-11-03 07:59:35.000000000 +0000 +++ apt-1.0.9.7ubuntu3/apt-pkg/deb/debsrcrecords.h 2015-03-23 07:59:06.000000000 +0000 @@ -53,6 +53,7 @@ return std::string(Start,Stop); }; virtual bool Files(std::vector &F); + bool Files2(std::vector &F); debSrcRecordParser(std::string const &File,pkgIndexFile const *Index) : Parser(Index), Fd(File,FileFd::ReadOnly, FileFd::Extension), Tags(&Fd,102400), diff -Nru apt-1.0.9.3ubuntu1/apt-pkg/deb/dpkgpm.cc apt-1.0.9.7ubuntu3/apt-pkg/deb/dpkgpm.cc --- apt-1.0.9.3ubuntu1/apt-pkg/deb/dpkgpm.cc 2014-11-03 07:59:35.000000000 +0000 +++ apt-1.0.9.7ubuntu3/apt-pkg/deb/dpkgpm.cc 2015-03-23 07:59:06.000000000 +0000 @@ -72,7 +72,9 @@ public: pkgDPkgPMPrivate() : stdin_is_dev_null(false), dpkgbuf_pos(0), term_out(NULL), history_out(NULL), - progress(NULL), master(-1), slave(NULL) + progress(NULL), tt_is_valid(false), master(-1), + slave(NULL), protect_slave_from_dying(-1), + direct_stdin(false) { dpkgbuf[0] = '\0'; } @@ -90,13 +92,16 @@ // pty stuff struct termios tt; + bool tt_is_valid; int master; char * slave; + int protect_slave_from_dying; // signals sigset_t sigmask; sigset_t original_sigmask; + bool direct_stdin; }; namespace @@ -1044,6 +1049,12 @@ PackagesTotal++; } } + /* one extra: We don't want the progress bar to reach 100%, especially not + if we call dpkg --configure --pending and process a bunch of triggers + while showing 100%. Also, spindown takes a while, so never reaching 100% + is way more correct than reaching 100% while still doing stuff even if + doing it this way is slightly bending the rules */ + ++PackagesTotal; } /*}}}*/ #if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13) @@ -1070,48 +1081,44 @@ return; } + if (isatty(STDIN_FILENO) == 0) + d->direct_stdin = true; + _error->PushToStack(); - // if tcgetattr for both stdin/stdout returns 0 (no error) - // we do the pty magic - if (tcgetattr(STDOUT_FILENO, &d->tt) == 0 && - tcgetattr(STDIN_FILENO, &d->tt) == 0) - { - d->master = posix_openpt(O_RDWR | O_NOCTTY); - if (d->master == -1) - _error->Errno("posix_openpt", _("Can not write log (%s)"), _("Is /dev/pts mounted?")); - else if (unlockpt(d->master) == -1) - { - _error->Errno("unlockpt", "Unlocking the slave of master fd %d failed!", d->master); - close(d->master); - d->master = -1; - } + + d->master = posix_openpt(O_RDWR | O_NOCTTY); + if (d->master == -1) + _error->Errno("posix_openpt", _("Can not write log (%s)"), _("Is /dev/pts mounted?")); + else if (unlockpt(d->master) == -1) + _error->Errno("unlockpt", "Unlocking the slave of master fd %d failed!", d->master); + else + { + char const * const slave_name = ptsname(d->master); + if (slave_name == NULL) + _error->Errno("ptsname", "Getting name for slave of master fd %d failed!", d->master); else { - char const * const slave_name = ptsname(d->master); - if (slave_name == NULL) - { - _error->Errno("unlockpt", "Getting name for slave of master fd %d failed!", d->master); - close(d->master); - d->master = -1; - } - else + d->slave = strdup(slave_name); + if (d->slave == NULL) + _error->Errno("strdup", "Copying name %s for slave of master fd %d failed!", slave_name, d->master); + else if (grantpt(d->master) == -1) + _error->Errno("grantpt", "Granting access to slave %s based on master fd %d failed!", slave_name, d->master); + else if (tcgetattr(STDIN_FILENO, &d->tt) == 0) { - d->slave = strdup(slave_name); - if (d->slave == NULL) + d->tt_is_valid = true; + struct termios raw_tt; + // copy window size of stdout if its a 'good' terminal + if (tcgetattr(STDOUT_FILENO, &raw_tt) == 0) { - _error->Errno("strdup", "Copying name %s for slave of master fd %d failed!", slave_name, d->master); - close(d->master); - d->master = -1; + struct winsize win; + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) < 0) + _error->Errno("ioctl", "Getting TIOCGWINSZ from stdout failed!"); + if (ioctl(d->master, TIOCSWINSZ, &win) < 0) + _error->Errno("ioctl", "Setting TIOCSWINSZ for master fd %d failed!", d->master); } - struct winsize win; - if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) < 0) - _error->Errno("ioctl", "Getting TIOCGWINSZ from stdout failed!"); - if (ioctl(d->master, TIOCSWINSZ, &win) < 0) - _error->Errno("ioctl", "Setting TIOCSWINSZ for master fd %d failed!", d->master); if (tcsetattr(d->master, TCSANOW, &d->tt) == -1) _error->Errno("tcsetattr", "Setting in Start via TCSANOW for master fd %d failed!", d->master); - struct termios raw_tt; raw_tt = d->tt; cfmakeraw(&raw_tt); raw_tt.c_lflag &= ~ECHO; @@ -1123,18 +1130,22 @@ sigaddset(&d->sigmask, SIGTTOU); sigprocmask(SIG_BLOCK,&d->sigmask, &d->original_sigmask); if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw_tt) == -1) - _error->Errno("tcsetattr", "Setting in Start via TCSAFLUSH for stdout failed!"); + _error->Errno("tcsetattr", "Setting in Start via TCSAFLUSH for stdin failed!"); sigprocmask(SIG_SETMASK, &d->original_sigmask, NULL); + + } + if (d->slave != NULL) + { + /* on linux, closing (and later reopening) all references to the slave + makes the slave a death end, so we open it here to have one open all + the time. We could use this fd in SetupSlavePtyMagic() for linux, but + on kfreebsd we get an incorrect ("step like") output then while it has + no problem with closing all references… so to avoid platform specific + code here we combine both and be happy once more */ + d->protect_slave_from_dying = open(d->slave, O_RDWR | O_CLOEXEC | O_NOCTTY); } } } - else - { - // 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. - if (isatty(STDOUT_FILENO) == 1 || errno == EBADF) - _error->Errno("tcgetattr", _("Can not write log (%s)"), _("Is stdout a terminal?")); - } if (_error->PendingError() == true) { @@ -1143,44 +1154,60 @@ close(d->master); d->master = -1; } + if (d->slave != NULL) + { + free(d->slave); + d->slave = NULL; + } _error->DumpErrors(std::cerr); } _error->RevertToStack(); } void pkgDPkgPM::SetupSlavePtyMagic() { - if(d->master == -1) + if(d->master == -1 || d->slave == NULL) return; if (close(d->master) == -1) _error->FatalE("close", "Closing master %d in child failed!", d->master); + d->master = -1; if (setsid() == -1) _error->FatalE("setsid", "Starting a new session for child failed!"); - int const slaveFd = open(d->slave, O_RDWR); + int const slaveFd = open(d->slave, O_RDWR | O_NOCTTY); if (slaveFd == -1) _error->FatalE("open", _("Can not write log (%s)"), _("Is /dev/pts mounted?")); - - if (ioctl(slaveFd, TIOCSCTTY, 0) < 0) + else if (ioctl(slaveFd, TIOCSCTTY, 0) < 0) _error->FatalE("ioctl", "Setting TIOCSCTTY for slave fd %d failed!", slaveFd); else { - for (unsigned short i = 0; i < 3; ++i) + unsigned short i = 0; + if (d->direct_stdin == true) + ++i; + for (; i < 3; ++i) if (dup2(slaveFd, i) == -1) _error->FatalE("dup2", "Dupping %d to %d in child failed!", slaveFd, i); - if (tcsetattr(0, TCSANOW, &d->tt) < 0) + if (d->tt_is_valid == true && tcsetattr(STDIN_FILENO, TCSANOW, &d->tt) < 0) _error->FatalE("tcsetattr", "Setting in Setup via TCSANOW for slave fd %d failed!", slaveFd); } + + if (slaveFd != -1) + close(slaveFd); } void pkgDPkgPM::StopPtyMagic() { if (d->slave != NULL) free(d->slave); d->slave = NULL; + if (d->protect_slave_from_dying != -1) + { + close(d->protect_slave_from_dying); + d->protect_slave_from_dying = -1; + } if(d->master >= 0) { - if (tcsetattr(0, TCSAFLUSH, &d->tt) == -1) + if (d->tt_is_valid == true && tcsetattr(STDIN_FILENO, TCSAFLUSH, &d->tt) == -1) _error->FatalE("tcsetattr", "Setting in Stop via TCSAFLUSH for stdin failed!"); close(d->master); d->master = -1; @@ -1267,9 +1294,8 @@ // support subpressing of triggers processing for special // cases like d-i that runs the triggers handling manually - bool const SmartConf = (_config->Find("PackageManager::Configure", "all") != "all"); bool const TriggersPending = _config->FindB("DPkg::TriggersPending", false); - if (_config->FindB("DPkg::ConfigurePending", SmartConf) == true) + if (_config->FindB("DPkg::ConfigurePending", true) == true) List.push_back(Item(Item::ConfigurePending, PkgIterator())); // for the progress @@ -1578,8 +1604,8 @@ // wait for input or output here FD_ZERO(&rfds); - if (d->master >= 0 && !d->stdin_is_dev_null) - FD_SET(0, &rfds); + if (d->master >= 0 && d->direct_stdin == false && d->stdin_is_dev_null == false) + FD_SET(STDIN_FILENO, &rfds); FD_SET(_dpkgin, &rfds); if(d->master >= 0) FD_SET(d->master, &rfds); diff -Nru apt-1.0.9.3ubuntu1/apt-pkg/depcache.cc apt-1.0.9.7ubuntu3/apt-pkg/depcache.cc --- apt-1.0.9.3ubuntu1/apt-pkg/depcache.cc 2014-11-03 07:59:35.000000000 +0000 +++ apt-1.0.9.7ubuntu3/apt-pkg/depcache.cc 2015-03-23 07:59:06.000000000 +0000 @@ -1226,7 +1226,7 @@ continue; } // now check if we should consider it a automatic dependency or not - if(InstPkg->CurrentVer == 0 && Pkg->Section != 0 && ConfigValueInSubTree("APT::Never-MarkAuto-Sections", Pkg.Section())) + if(InstPkg->CurrentVer == 0 && InstVer->Section != 0 && ConfigValueInSubTree("APT::Never-MarkAuto-Sections", InstVer.Section())) { if(DebugAutoInstall == true) std::clog << OutputInDepth(Depth) << "Setting NOT as auto-installed (direct " diff -Nru apt-1.0.9.3ubuntu1/apt-pkg/pkgcache.cc apt-1.0.9.7ubuntu3/apt-pkg/pkgcache.cc --- apt-1.0.9.3ubuntu1/apt-pkg/pkgcache.cc 2014-11-03 07:59:35.000000000 +0000 +++ apt-1.0.9.7ubuntu3/apt-pkg/pkgcache.cc 2015-03-23 07:59:06.000000000 +0000 @@ -524,7 +524,10 @@ out << " -> " << candidate; if ( newest != "none" && candidate != newest) out << " | " << newest; - out << " > ( " << string(Pkg.Section()==0?"none":Pkg.Section()) << " )"; + if (Pkg->VersionList == 0) + out << " > ( none )"; + else + out << " > ( " << string(Pkg.VersionList().Section()==0?"unknown":Pkg.VersionList().Section()) << " )"; return out; } /*}}}*/ diff -Nru apt-1.0.9.3ubuntu1/apt-pkg/srcrecords.cc apt-1.0.9.7ubuntu3/apt-pkg/srcrecords.cc --- apt-1.0.9.3ubuntu1/apt-pkg/srcrecords.cc 2014-11-03 07:59:35.000000000 +0000 +++ apt-1.0.9.7ubuntu3/apt-pkg/srcrecords.cc 2015-03-23 07:59:06.000000000 +0000 @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -147,5 +148,33 @@ return fields[Type]; } /*}}}*/ - - +bool pkgSrcRecords::Parser::Files2(std::vector &F2)/*{{{*/ +{ + debSrcRecordParser * const deb = dynamic_cast(this); + if (deb != NULL) + return deb->Files2(F2); + + std::vector F; + if (Files(F) == false) + return false; + for (std::vector::const_iterator f = F.begin(); f != F.end(); ++f) + { + pkgSrcRecords::File2 f2; +#if __GNUC__ >= 4 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif + f2.MD5Hash = f->MD5Hash; + f2.Size = f->Size; + f2.Hashes.push_back(HashString("MD5Sum", f->MD5Hash)); + f2.FileSize = f->Size; +#if __GNUC__ >= 4 + #pragma GCC diagnostic pop +#endif + f2.Path = f->Path; + f2.Type = f->Type; + F2.push_back(f2); + } + return true; +} + /*}}}*/ diff -Nru apt-1.0.9.3ubuntu1/apt-pkg/srcrecords.h apt-1.0.9.7ubuntu3/apt-pkg/srcrecords.h --- apt-1.0.9.3ubuntu1/apt-pkg/srcrecords.h 2014-11-03 07:59:35.000000000 +0000 +++ apt-1.0.9.7ubuntu3/apt-pkg/srcrecords.h 2015-03-23 07:59:06.000000000 +0000 @@ -14,6 +14,7 @@ #define PKGLIB_SRCRECORDS_H #include +#include #include #include @@ -29,15 +30,28 @@ { public: +#if __GNUC__ >= 4 + // ensure that con- & de-structor don't trigger this warning + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif // Describes a single file struct File { - std::string MD5Hash; - unsigned long Size; + APT_DEPRECATED std::string MD5Hash; + APT_DEPRECATED unsigned long Size; std::string Path; std::string Type; }; - + struct File2 : public File + { + unsigned long long FileSize; + HashStringList Hashes; + }; +#if __GNUC__ >= 4 + #pragma GCC diagnostic pop +#endif + // Abstract parser for each source record class Parser { @@ -77,6 +91,7 @@ static const char *BuildDepType(unsigned char const &Type) APT_PURE; virtual bool Files(std::vector &F) = 0; + bool Files2(std::vector &F); Parser(const pkgIndexFile *Index) : iIndex(Index) {}; virtual ~Parser() {}; diff -Nru apt-1.0.9.3ubuntu1/apt-private/private-cmndline.cc apt-1.0.9.7ubuntu3/apt-private/private-cmndline.cc --- apt-1.0.9.3ubuntu1/apt-private/private-cmndline.cc 2014-11-03 07:59:35.000000000 +0000 +++ apt-1.0.9.7ubuntu3/apt-private/private-cmndline.cc 2015-03-23 07:59:06.000000000 +0000 @@ -166,7 +166,7 @@ if (CmdMatches("install", "remove", "purge", "upgrade", "dist-upgrade", "deselect-upgrade", "autoremove", "clean", "autoclean", "check", - "build-dep", "full-upgrade")) + "build-dep", "full-upgrade", "source")) { addArg('s', "simulate", "APT::Get::Simulate", 0); addArg('s', "just-print", "APT::Get::Simulate", 0); diff -Nru apt-1.0.9.3ubuntu1/cmdline/apt-get.cc apt-1.0.9.7ubuntu3/cmdline/apt-get.cc --- apt-1.0.9.3ubuntu1/cmdline/apt-get.cc 2014-11-03 07:59:35.000000000 +0000 +++ apt-1.0.9.7ubuntu3/cmdline/apt-get.cc 2015-03-23 07:59:06.000000000 +0000 @@ -797,13 +797,13 @@ } // Back track - vector Lst; - if (Last->Files(Lst) == false) { + vector Lst; + if (Last->Files2(Lst) == false) { return false; } // Load them into the fetcher - for (vector::const_iterator I = Lst.begin(); + for (vector::const_iterator I = Lst.begin(); I != Lst.end(); ++I) { // Try to guess what sort of file it is we are getting. @@ -832,22 +832,26 @@ queued.insert(Last->Index().ArchiveURI(I->Path)); // check if we have a file with that md5 sum already localy - if(!I->MD5Hash.empty() && FileExists(flNotDir(I->Path))) - { - FileFd Fd(flNotDir(I->Path), FileFd::ReadOnly); - MD5Summation sum; - sum.AddFD(Fd.Fd(), Fd.Size()); - Fd.Close(); - if((string)sum.Result() == I->MD5Hash) + std::string localFile = flNotDir(I->Path); + if (FileExists(localFile) == true) + if(I->Hashes.VerifyFile(localFile) == true) { ioprintf(c1out,_("Skipping already downloaded file '%s'\n"), - flNotDir(I->Path).c_str()); + localFile.c_str()); continue; } + + // see if we have a hash (Acquire::ForceHash is the only way to have none) + HashString const * const hs = I->Hashes.find(NULL); + if (hs == NULL && _config->FindB("APT::Get::AllowUnauthenticated",false) == false) + { + ioprintf(c1out, "Skipping download of file '%s' as requested hashsum is not available for authentication\n", + localFile.c_str()); + continue; } new pkgAcqFile(&Fetcher,Last->Index().ArchiveURI(I->Path), - I->MD5Hash,I->Size, + hs != NULL ? hs->toStr() : "", I->FileSize, Last->Index().SourceInfo(*Last,*I),Src); } } diff -Nru apt-1.0.9.3ubuntu1/cmdline/apt-helper.cc apt-1.0.9.7ubuntu3/cmdline/apt-helper.cc --- apt-1.0.9.3ubuntu1/cmdline/apt-helper.cc 2014-11-03 07:59:35.000000000 +0000 +++ apt-1.0.9.7ubuntu3/cmdline/apt-helper.cc 2015-03-23 07:59:06.000000000 +0000 @@ -48,23 +48,34 @@ if (CmdL.FileSize() <= 2) return _error->Error(_("Must specify at least one pair url/filename")); - pkgAcquire Fetcher; AcqTextStatus Stat(ScreenWidth, _config->FindI("quiet",0)); Fetcher.Setup(&Stat); - std::string download_uri = CmdL.FileList[1]; - std::string targetfile = CmdL.FileList[2]; - std::string hash; - if (CmdL.FileSize() > 3) - hash = CmdL.FileList[3]; - // we use download_uri as descr and targetfile as short-descr - new pkgAcqFile(&Fetcher, download_uri, hash, 0, download_uri, targetfile, - "dest-dir-ignored", targetfile); - Fetcher.Run(); + + size_t fileind = 0; + std::vector targetfiles; + while (fileind + 2 <= CmdL.FileSize()) + { + std::string download_uri = CmdL.FileList[fileind + 1]; + std::string targetfile = CmdL.FileList[fileind + 2]; + std::string hash; + if (CmdL.FileSize() > fileind + 3) + hash = CmdL.FileList[fileind + 3]; + // we use download_uri as descr and targetfile as short-descr + new pkgAcqFile(&Fetcher, download_uri, hash, 0, download_uri, targetfile, + "dest-dir-ignored", targetfile); + targetfiles.push_back(targetfile); + fileind += 3; + } + bool Failed = false; - if (AcquireRun(Fetcher, 0, &Failed, NULL) == false || Failed == true || - FileExists(targetfile) == false) + if (AcquireRun(Fetcher, 0, &Failed, NULL) == false || Failed == true) return _error->Error(_("Download Failed")); + if (targetfiles.empty() == false) + for (std::vector::const_iterator f = targetfiles.begin(); f != targetfiles.end(); ++f) + if (FileExists(*f) == false) + return _error->Error(_("Download Failed")); + return true; } diff -Nru apt-1.0.9.3ubuntu1/cmdline/apt-key.in apt-1.0.9.7ubuntu3/cmdline/apt-key.in --- apt-1.0.9.3ubuntu1/cmdline/apt-key.in 2014-11-03 07:59:35.000000000 +0000 +++ apt-1.0.9.7ubuntu3/cmdline/apt-key.in 2015-03-23 07:59:06.000000000 +0000 @@ -180,7 +180,7 @@ remove_key_from_keyring() { local GPG="$GPG_CMD --keyring $1" # check if the key is in this keyring: the key id is in the 5 column at the end - if ! $GPG --with-colons --list-keys 2>&1 | grep -q "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]\+$2:"; then + if ! $GPG --with-colons --list-keys 2>&1 | grep -q "^pub:[^:]*:[^:]*:[^:]*:[0-9A-F]*$2:"; then return fi if [ ! -w "$1" ]; then diff -Nru apt-1.0.9.3ubuntu1/configure apt-1.0.9.7ubuntu3/configure --- apt-1.0.9.3ubuntu1/configure 2014-11-03 08:01:40.000000000 +0000 +++ apt-1.0.9.7ubuntu3/configure 2015-03-23 07:59:56.000000000 +0000 @@ -2436,7 +2436,7 @@ PACKAGE="apt" -PACKAGE_VERSION="1.0.9.3ubuntu1" +PACKAGE_VERSION="1.0.9.7ubuntu3" PACKAGE_MAIL="APT Development Team " cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" diff -Nru apt-1.0.9.3ubuntu1/configure.ac apt-1.0.9.7ubuntu3/configure.ac --- apt-1.0.9.3ubuntu1/configure.ac 2014-11-03 08:01:38.000000000 +0000 +++ apt-1.0.9.7ubuntu3/configure.ac 2015-03-23 07:59:55.000000000 +0000 @@ -18,7 +18,7 @@ AC_CONFIG_HEADER(include/config.h:buildlib/config.h.in include/apti18n.h:buildlib/apti18n.h.in) PACKAGE="apt" -PACKAGE_VERSION="1.0.9.3ubuntu1" +PACKAGE_VERSION="1.0.9.7ubuntu3" PACKAGE_MAIL="APT Development Team " AC_DEFINE_UNQUOTED(PACKAGE,"$PACKAGE") AC_DEFINE_UNQUOTED(PACKAGE_VERSION,"$PACKAGE_VERSION") diff -Nru apt-1.0.9.3ubuntu1/debian/apt.auto-removal.sh apt-1.0.9.7ubuntu3/debian/apt.auto-removal.sh --- apt-1.0.9.3ubuntu1/debian/apt.auto-removal.sh 2014-11-03 07:59:35.000000000 +0000 +++ apt-1.0.9.7ubuntu3/debian/apt.auto-removal.sh 2015-03-23 07:59:06.000000000 +0000 @@ -41,7 +41,7 @@ return "$?" } -list="$(${DPKG} -l | awk '/^ii[ ]+(linux|kfreebsd|gnumach)-image-[0-9]/ && $2 !~ /-dbg$/ { print $2 }' | sed -e 's#\(linux\|kfreebsd\|gnumach\)-image-##')" +list="$(${DPKG} -l | awk '/^ii[ ]+(linux|kfreebsd|gnumach)-image-[0-9]+\./ && $2 !~ /-dbg$/ { print $2 }' | sed -e 's#\(linux\|kfreebsd\|gnumach\)-image-##')" latest_version="" previous_version="" diff -Nru apt-1.0.9.3ubuntu1/debian/changelog apt-1.0.9.7ubuntu3/debian/changelog --- apt-1.0.9.3ubuntu1/debian/changelog 2014-11-03 07:59:35.000000000 +0000 +++ apt-1.0.9.7ubuntu3/debian/changelog 2015-03-23 07:59:06.000000000 +0000 @@ -1,3 +1,109 @@ +apt (1.0.9.7ubuntu3) vivid; urgency=medium + + * test/integration/test-apt-download-progress: + - give apt more time to gather download data in test + + -- Michael Vogt Mon, 23 Mar 2015 08:56:53 +0100 + +apt (1.0.9.7ubuntu2) vivid; urgency=medium + + * test/integration/test-apt-download-progress: + - fix test failure on fast hardware + + -- Michael Vogt Fri, 20 Mar 2015 17:42:01 +0100 + +apt (1.0.9.7ubuntu1) vivid; urgency=low + + * Merged fixes from debian/sid (LP: #1431877) + + -- Michael Vogt Mon, 16 Mar 2015 11:09:30 +0100 + +apt (1.0.9.7) unstable; urgency=medium + + [ Tomasz Buchert ] + * Fix crash in the apt-transport-https when Owner is NULL (Closes: #778375) + + -- Michael Vogt Mon, 23 Feb 2015 12:54:03 +0100 + +apt (1.0.9.6) unstable; urgency=medium + + [ Michael Vogt ] + * Fix missing URIStart() for https downloads + * Add regression test for the previous commit + + [ David Kalnischkies ] + * 128 KiB DSC files ought to be enough for everyone (Closes: 774893) + * award points for positive dependencies again (Closes: 774924) + + -- Michael Vogt Fri, 16 Jan 2015 08:37:25 +0100 + +apt (1.0.9.5) unstable; urgency=medium + + [ David Kalnischkies ] + * dispose http(s) 416 error page as non-content (Closes: 768797) + * do not make PTY slave the controlling terminal (Closes: 772641) + * always run 'dpkg --configure -a' at the end of our dpkg callings + (Closes: 769609) + * pass-through stdin fd instead of content if not a terminal (Closes: 773061) + + [ James McCoy ] + * tighten filtering of kernel images in apt.auto-removal (Closes: 772732) + + [ Jean-Pierre Giraud ] + * French manpages translation update (Closes: 771967) + + [ Zhou Mo ] + * Chinese (simplified) program translation update (Closes: 771982) + + [ Kenshi Muto ] + * Japanese program translation update (Closes: 772678) + + [ Theppitak Karoonboonyanan ] + * Thai program translation update (Closes: 772913) + + -- David Kalnischkies Tue, 23 Dec 2014 13:22:42 +0100 + +apt (1.0.9.4) unstable; urgency=medium + + [ David Kalnischkies ] + * use 'best' hash for source authentication (LP: 1098738) + * deprecate the Section member from package struct + * allow options between command and -- on commandline + * re-enable support for -s (and co) in apt-get source (Closes: 742578) + * change codenames to jessie as stable POV in docs + * close leaking slave fd after setting up pty magic (Closes: 767774) + * fix PTY interaction on linux and kfreebsd (Closes: 765687) + + [ James McCoy ] + * support long keyids in "apt-key del" instead of ignoring them + (Closes: 754436) + + [ Michael Vogt ] + * Use sysconf(_SC_ARG_MAX) to find the size of Dpkg::MaxArgBytes + + [ Frans Spiesschaert ] + * Dutch program translation update (Closes: 771039) + + [ Julien Patriarca ] + * French program translation update (Closes: 766755) + + [ Zhou Mo ] + * Chinese (simplified) program translation update (Closes: 766170) + + [ Miroslav Kure ] + * Czech program translation update (Closes: 764055) + + [ Mert Dirik ] + * Turkish program translation update (Closes: 763379) + + [ Kenshi Muto ] + * Japanese program translation update (Closes: 763033) + + [ Manuel "Venturi" Porras Peralta ] + * Spanish program translation update (Closes: 771815) + + -- David Kalnischkies Wed, 03 Dec 2014 14:26:04 +0100 + apt (1.0.9.3ubuntu1) vivid; urgency=low * Merged from debian/sid, remaining changes: diff -Nru apt-1.0.9.3ubuntu1/debian/libapt-pkg4.12.symbols apt-1.0.9.7ubuntu3/debian/libapt-pkg4.12.symbols --- apt-1.0.9.3ubuntu1/debian/libapt-pkg4.12.symbols 2014-11-03 07:59:35.000000000 +0000 +++ apt-1.0.9.7ubuntu3/debian/libapt-pkg4.12.symbols 2015-03-23 07:59:06.000000000 +0000 @@ -1579,6 +1579,16 @@ (c++)"typeinfo for debTranslationsParser@Base" 1.0.4 (c++)"typeinfo name for debTranslationsParser@Base" 1.0.4 (c++)"vtable for debTranslationsParser@Base" 1.0.4 + (c++)"HashStringList::find(char const*) const@Base" 1.0.9.4 + (c++)"HashStringList::operator==(HashStringList const&) const@Base" 1.0.9.4 + (c++)"HashStringList::operator!=(HashStringList const&) const@Base" 1.0.9.4 + (c++)"HashStringList::push_back(HashString const&)@Base" 1.0.9.4 + (c++)"HashStringList::supported(char const*)@Base" 1.0.9.4 + (c++)"HashStringList::VerifyFile(std::basic_string, std::allocator >) const@Base" 1.0.9.4 + (c++)"HashString::operator==(HashString const&) const@Base" 1.0.9.4 + (c++)"HashString::operator!=(HashString const&) const@Base" 1.0.9.4 + (c++)"pkgSrcRecords::Parser::Files2(std::vector >&)@Base" 1.0.9.4 + (c++)"debSrcRecordParser::Files2(std::vector >&)@Base" 1.0.9.4 ### demangle strangeness - buildd report it as MISSING and as new… (c++)"pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire*, std::basic_string, std::allocator >, std::basic_string, std::allocator >, std::basic_string, std::allocator >, std::basic_string, std::allocator >, std::basic_string, std::allocator >, std::basic_string, std::allocator >, std::vector > const*, indexRecords*)@Base" 0.8.0 ### gcc-4.6 artefacts diff -Nru apt-1.0.9.3ubuntu1/doc/apt-verbatim.ent apt-1.0.9.7ubuntu3/doc/apt-verbatim.ent --- apt-1.0.9.3ubuntu1/doc/apt-verbatim.ent 2014-11-03 08:01:38.000000000 +0000 +++ apt-1.0.9.7ubuntu3/doc/apt-verbatim.ent 2015-03-23 07:59:55.000000000 +0000 @@ -225,13 +225,13 @@ "> - + - - - - + + + +