diff options
Diffstat (limited to 'apt-pkg')
70 files changed, 3395 insertions, 1168 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 566f51606..c31d5d2b3 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -94,7 +94,7 @@ void pkgAcquire::Item::Failed(string Message,pkgAcquire::MethodConfig *Cnf) // --------------------------------------------------------------------- /* Stash status and the file size. Note that setting Complete means sub-phases of the acquire process such as decompresion are operating */ -void pkgAcquire::Item::Start(string /*Message*/,unsigned long Size) +void pkgAcquire::Item::Start(string /*Message*/,unsigned long long Size) { Status = StatFetching; if (FileSize == 0 && Complete == false) @@ -104,7 +104,7 @@ void pkgAcquire::Item::Start(string /*Message*/,unsigned long Size) // Acquire::Item::Done - Item downloaded OK /*{{{*/ // --------------------------------------------------------------------- /* */ -void pkgAcquire::Item::Done(string Message,unsigned long Size,string Hash, +void pkgAcquire::Item::Done(string Message,unsigned long long Size,string Hash, pkgAcquire::MethodConfig *Cnf) { // We just downloaded something.. @@ -245,7 +245,7 @@ void pkgAcqSubIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{* } } /*}}}*/ -void pkgAcqSubIndex::Done(string Message,unsigned long Size,string Md5Hash, /*{{{*/ +void pkgAcqSubIndex::Done(string Message,unsigned long long Size,string Md5Hash, /*{{{*/ pkgAcquire::MethodConfig *Cnf) { if(Debug) @@ -544,7 +544,7 @@ void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{ Dequeue(); } /*}}}*/ -void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash, /*{{{*/ +void pkgAcqDiffIndex::Done(string Message,unsigned long long Size,string Md5Hash, /*{{{*/ pkgAcquire::MethodConfig *Cnf) { if(Debug) @@ -710,7 +710,7 @@ bool pkgAcqIndexDiffs::QueueNextDiff() /*{{{*/ return true; } /*}}}*/ -void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash, /*{{{*/ +void pkgAcqIndexDiffs::Done(string Message,unsigned long long Size,string Md5Hash, /*{{{*/ pkgAcquire::MethodConfig *Cnf) { if(Debug) @@ -881,7 +881,7 @@ void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/ to the uncompressed version of the file. If this is so the file is copied into the partial directory. In all other cases the file is decompressed with a gzip uri. */ -void pkgAcqIndex::Done(string Message,unsigned long Size,string Hash, +void pkgAcqIndex::Done(string Message,unsigned long long Size,string Hash, pkgAcquire::MethodConfig *Cfg) { Item::Done(Message,Size,Hash,Cfg); @@ -1123,7 +1123,7 @@ string pkgAcqMetaSig::Custom600Headers() return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime); } -void pkgAcqMetaSig::Done(string Message,unsigned long Size,string MD5, +void pkgAcqMetaSig::Done(string Message,unsigned long long Size,string MD5, pkgAcquire::MethodConfig *Cfg) { Item::Done(Message,Size,MD5,Cfg); @@ -1232,7 +1232,7 @@ string pkgAcqMetaIndex::Custom600Headers() return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime); } /*}}}*/ -void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string Hash, /*{{{*/ +void pkgAcqMetaIndex::Done(string Message,unsigned long long Size,string Hash, /*{{{*/ pkgAcquire::MethodConfig *Cfg) { Item::Done(Message,Size,Hash,Cfg); @@ -1734,6 +1734,8 @@ bool pkgAcqArchive::QueueNext() string PkgFile = Parse.FileName(); if (ForceHash.empty() == false) { + if(stringcasecmp(ForceHash, "sha512") == 0) + ExpectedHash = HashString("SHA512", Parse.SHA512Hash()); if(stringcasecmp(ForceHash, "sha256") == 0) ExpectedHash = HashString("SHA256", Parse.SHA256Hash()); else if (stringcasecmp(ForceHash, "sha1") == 0) @@ -1744,7 +1746,9 @@ bool pkgAcqArchive::QueueNext() else { string Hash; - if ((Hash = Parse.SHA256Hash()).empty() == false) + if ((Hash = Parse.SHA512Hash()).empty() == false) + ExpectedHash = HashString("SHA512", Hash); + else if ((Hash = Parse.SHA256Hash()).empty() == false) ExpectedHash = HashString("SHA256", Hash); else if ((Hash = Parse.SHA1Hash()).empty() == false) ExpectedHash = HashString("SHA1", Hash); @@ -1768,7 +1772,7 @@ bool pkgAcqArchive::QueueNext() if (stat(FinalFile.c_str(),&Buf) == 0) { // Make sure the size matches - if ((unsigned)Buf.st_size == Version->Size) + if ((unsigned long long)Buf.st_size == Version->Size) { Complete = true; Local = true; @@ -1787,7 +1791,7 @@ bool pkgAcqArchive::QueueNext() if (stat(FinalFile.c_str(),&Buf) == 0) { // Make sure the size matches - if ((unsigned)Buf.st_size == Version->Size) + if ((unsigned long long)Buf.st_size == Version->Size) { Complete = true; Local = true; @@ -1807,7 +1811,7 @@ bool pkgAcqArchive::QueueNext() if (stat(DestFile.c_str(),&Buf) == 0) { // Hmm, the partial file is too big, erase it - if ((unsigned)Buf.st_size > Version->Size) + if ((unsigned long long)Buf.st_size > Version->Size) unlink(DestFile.c_str()); else PartialSize = Buf.st_size; @@ -1830,7 +1834,7 @@ bool pkgAcqArchive::QueueNext() // AcqArchive::Done - Finished fetching /*{{{*/ // --------------------------------------------------------------------- /* */ -void pkgAcqArchive::Done(string Message,unsigned long Size,string CalcHash, +void pkgAcqArchive::Done(string Message,unsigned long long Size,string CalcHash, pkgAcquire::MethodConfig *Cfg) { Item::Done(Message,Size,CalcHash,Cfg); @@ -1941,7 +1945,7 @@ void pkgAcqArchive::Finished() // --------------------------------------------------------------------- /* The file is added to the queue */ pkgAcqFile::pkgAcqFile(pkgAcquire *Owner,string URI,string Hash, - unsigned long Size,string Dsc,string ShortDesc, + unsigned long long Size,string Dsc,string ShortDesc, const string &DestDir, const string &DestFilename, bool IsIndexFile) : Item(Owner), ExpectedHash(Hash), IsIndexFile(IsIndexFile) @@ -1969,7 +1973,7 @@ pkgAcqFile::pkgAcqFile(pkgAcquire *Owner,string URI,string Hash, if (stat(DestFile.c_str(),&Buf) == 0) { // Hmm, the partial file is too big, erase it - if ((unsigned)Buf.st_size > Size) + if ((unsigned long long)Buf.st_size > Size) unlink(DestFile.c_str()); else PartialSize = Buf.st_size; @@ -1981,7 +1985,7 @@ pkgAcqFile::pkgAcqFile(pkgAcquire *Owner,string URI,string Hash, // AcqFile::Done - Item downloaded OK /*{{{*/ // --------------------------------------------------------------------- /* */ -void pkgAcqFile::Done(string Message,unsigned long Size,string CalcHash, +void pkgAcqFile::Done(string Message,unsigned long long Size,string CalcHash, pkgAcquire::MethodConfig *Cnf) { Item::Done(Message,Size,CalcHash,Cnf); @@ -2069,13 +2073,3 @@ string pkgAcqFile::Custom600Headers() return ""; } /*}}}*/ -bool IndexTarget::IsOptional() const { - if (strncmp(ShortDesc.c_str(), "Translation", 11) != 0) - return false; - return true; -} -bool IndexTarget::IsSubIndex() const { - if (ShortDesc != "TranslationIndex") - return false; - return true; -} diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h index f763577ee..f39a90c0b 100644 --- a/apt-pkg/acquire-item.h +++ b/apt-pkg/acquire-item.h @@ -194,7 +194,7 @@ class pkgAcquire::Item : public WeakPointable * * \sa pkgAcqMethod */ - virtual void Done(string Message,unsigned long Size,string Hash, + virtual void Done(string Message,unsigned long long Size,string Hash, pkgAcquire::MethodConfig *Cnf); /** \brief Invoked when the worker starts to fetch this object. @@ -206,7 +206,7 @@ class pkgAcquire::Item : public WeakPointable * * \sa pkgAcqMethod */ - virtual void Start(string Message,unsigned long Size); + virtual void Start(string Message,unsigned long long Size); /** \brief Custom headers to be sent to the fetch process. * @@ -309,7 +309,7 @@ class pkgAcqSubIndex : public pkgAcquire::Item public: // Specialized action members virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf); - virtual void Done(string Message,unsigned long Size,string Md5Hash, + virtual void Done(string Message,unsigned long long Size,string Md5Hash, pkgAcquire::MethodConfig *Cnf); virtual string DescURI() {return Desc.URI;}; virtual string Custom600Headers(); @@ -372,7 +372,7 @@ class pkgAcqDiffIndex : public pkgAcquire::Item public: // Specialized action members virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf); - virtual void Done(string Message,unsigned long Size,string Md5Hash, + virtual void Done(string Message,unsigned long long Size,string Md5Hash, pkgAcquire::MethodConfig *Cnf); virtual string DescURI() {return RealURI + "Index";}; virtual string Custom600Headers(); @@ -508,7 +508,7 @@ class pkgAcqIndexDiffs : public pkgAcquire::Item */ virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf); - virtual void Done(string Message,unsigned long Size,string Md5Hash, + virtual void Done(string Message,unsigned long long Size,string Md5Hash, pkgAcquire::MethodConfig *Cnf); virtual string DescURI() {return RealURI + "Index";}; @@ -581,7 +581,7 @@ class pkgAcqIndex : public pkgAcquire::Item // Specialized action members virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf); - virtual void Done(string Message,unsigned long Size,string Md5Hash, + virtual void Done(string Message,unsigned long long Size,string Md5Hash, pkgAcquire::MethodConfig *Cnf); virtual string Custom600Headers(); virtual string DescURI() {return Desc.URI;}; @@ -646,8 +646,9 @@ class pkgAcqIndexTrans : public pkgAcqIndex }; /*}}}*/ /** \brief Information about an index file. */ /*{{{*/ -struct IndexTarget +class IndexTarget { + public: /** \brief A URI from which the index file can be downloaded. */ string URI; @@ -662,14 +663,28 @@ struct IndexTarget */ string MetaKey; - //FIXME: We should use virtual methods here instead… - bool IsOptional() const; - bool IsSubIndex() const; + virtual bool IsOptional() const { + return false; + } + virtual bool IsSubIndex() const { + return false; + } }; /*}}}*/ /** \brief Information about an optional index file. */ /*{{{*/ -struct OptionalIndexTarget : public IndexTarget +class OptionalIndexTarget : public IndexTarget +{ + virtual bool IsOptional() const { + return true; + } +}; + /*}}}*/ +/** \brief Information about an subindex index file. */ /*{{{*/ +class SubIndexTarget : public IndexTarget { + virtual bool IsSubIndex() const { + return true; + } }; /*}}}*/ @@ -723,7 +738,7 @@ class pkgAcqMetaSig : public pkgAcquire::Item // Specialized action members virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf); - virtual void Done(string Message,unsigned long Size,string Md5Hash, + virtual void Done(string Message,unsigned long long Size,string Md5Hash, pkgAcquire::MethodConfig *Cnf); virtual string Custom600Headers(); virtual string DescURI() {return RealURI; }; @@ -818,7 +833,7 @@ class pkgAcqMetaIndex : public pkgAcquire::Item // Specialized action members virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf); - virtual void Done(string Message,unsigned long Size, string Hash, + virtual void Done(string Message,unsigned long long Size, string Hash, pkgAcquire::MethodConfig *Cnf); virtual string Custom600Headers(); virtual string DescURI() {return RealURI; }; @@ -918,7 +933,7 @@ class pkgAcqArchive : public pkgAcquire::Item public: virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf); - virtual void Done(string Message,unsigned long Size,string Hash, + virtual void Done(string Message,unsigned long long Size,string Hash, pkgAcquire::MethodConfig *Cnf); virtual string DescURI() {return Desc.URI;}; virtual string ShortDesc() {return Desc.ShortDesc;}; @@ -975,7 +990,7 @@ class pkgAcqFile : public pkgAcquire::Item // Specialized action members virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf); - virtual void Done(string Message,unsigned long Size,string CalcHash, + virtual void Done(string Message,unsigned long long Size,string CalcHash, pkgAcquire::MethodConfig *Cnf); virtual string DescURI() {return Desc.URI;}; virtual string HashSum() {return ExpectedHash.toStr(); }; @@ -1012,7 +1027,7 @@ class pkgAcqFile : public pkgAcquire::Item * is the absolute name to which the file should be downloaded. */ - pkgAcqFile(pkgAcquire *Owner, string URI, string Hash, unsigned long Size, + pkgAcqFile(pkgAcquire *Owner, string URI, string Hash, unsigned long long Size, string Desc, string ShortDesc, const string &DestDir="", const string &DestFilename="", bool IsIndexFile=false); diff --git a/apt-pkg/acquire-method.cc b/apt-pkg/acquire-method.cc index 7e9061e56..25c6c674d 100644 --- a/apt-pkg/acquire-method.cc +++ b/apt-pkg/acquire-method.cc @@ -166,6 +166,8 @@ void pkgAcqMethod::URIDone(FetchResult &Res, FetchResult *Alt) std::cout << "SHA1-Hash: " << Res.SHA1Sum << "\n"; if (Res.SHA256Sum.empty() == false) std::cout << "SHA256-Hash: " << Res.SHA256Sum << "\n"; + if (Res.SHA512Sum.empty() == false) + std::cout << "SHA512-Hash: " << Res.SHA512Sum << "\n"; if (UsedMirror.empty() == false) std::cout << "UsedMirror: " << UsedMirror << "\n"; if (Res.GPGVOutput.empty() == false) @@ -199,7 +201,9 @@ void pkgAcqMethod::URIDone(FetchResult &Res, FetchResult *Alt) std::cout << "Alt-SHA1-Hash: " << Alt->SHA1Sum << "\n"; if (Alt->SHA256Sum.empty() == false) std::cout << "Alt-SHA256-Hash: " << Alt->SHA256Sum << "\n"; - + if (Alt->SHA512Sum.empty() == false) + std::cout << "Alt-SHA512-Hash: " << Alt->SHA512Sum << "\n"; + if (Alt->IMSHit == true) std::cout << "Alt-IMS-Hit: true\n"; } @@ -456,5 +460,6 @@ void pkgAcqMethod::FetchResult::TakeHashes(Hashes &Hash) MD5Sum = Hash.MD5.Result(); SHA1Sum = Hash.SHA1.Result(); SHA256Sum = Hash.SHA256.Result(); + SHA512Sum = Hash.SHA512.Result(); } /*}}}*/ diff --git a/apt-pkg/acquire-method.h b/apt-pkg/acquire-method.h index 72efa8065..6551170c4 100644 --- a/apt-pkg/acquire-method.h +++ b/apt-pkg/acquire-method.h @@ -46,12 +46,13 @@ class pkgAcqMethod string MD5Sum; string SHA1Sum; string SHA256Sum; + string SHA512Sum; vector<string> GPGVOutput; time_t LastModified; bool IMSHit; string Filename; - unsigned long Size; - unsigned long ResumePoint; + unsigned long long Size; + unsigned long long ResumePoint; void TakeHashes(Hashes &Hash); FetchResult(); diff --git a/apt-pkg/acquire-worker.cc b/apt-pkg/acquire-worker.cc index 75e03232a..3e1fd98db 100644 --- a/apt-pkg/acquire-worker.cc +++ b/apt-pkg/acquire-worker.cc @@ -287,9 +287,9 @@ bool pkgAcquire::Worker::RunMessages() Log->Pulse(Owner->GetOwner()); OwnerQ->ItemDone(Itm); - unsigned long const ServerSize = atol(LookupTag(Message,"Size","0").c_str()); + unsigned long long const ServerSize = atoll(LookupTag(Message,"Size","0").c_str()); if (TotalSize != 0 && ServerSize != TotalSize) - _error->Warning("Size of file %s is not what the server reported %s %lu", + _error->Warning("Size of file %s is not what the server reported %s %llu", Owner->DestFile.c_str(), LookupTag(Message,"Size","0").c_str(),TotalSize); // see if there is a hash to verify diff --git a/apt-pkg/acquire-worker.h b/apt-pkg/acquire-worker.h index 06283922e..ce19091e4 100644 --- a/apt-pkg/acquire-worker.h +++ b/apt-pkg/acquire-worker.h @@ -44,6 +44,9 @@ */ class pkgAcquire::Worker : public WeakPointable { + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; + friend class pkgAcquire; protected: @@ -244,17 +247,17 @@ class pkgAcquire::Worker : public WeakPointable /** \brief How many bytes of the file have been downloaded. Zero * if the current progress of the file cannot be determined. */ - unsigned long CurrentSize; + unsigned long long CurrentSize; /** \brief The total number of bytes to be downloaded. Zero if the * total size of the final is unknown. */ - unsigned long TotalSize; + unsigned long long TotalSize; /** \brief How much of the file was already downloaded prior to * starting this worker. */ - unsigned long ResumePoint; + unsigned long long ResumePoint; /** \brief Tell the subprocess to download the given item. * @@ -314,7 +317,7 @@ class pkgAcquire::Worker : public WeakPointable * Closes the file descriptors; if MethodConfig::NeedsCleanup is * \b false, also rudely interrupts the worker with a SIGINT. */ - ~Worker(); + virtual ~Worker(); }; /** @} */ diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index a2da196be..8c00748b2 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -37,9 +37,9 @@ using namespace std; // Acquire::pkgAcquire - Constructor /*{{{*/ // --------------------------------------------------------------------- /* We grab some runtime state from the configuration space */ -pkgAcquire::pkgAcquire() : Queues(0), Workers(0), Configs(0), Log(NULL), ToFetch(0), +pkgAcquire::pkgAcquire() : LockFD(-1), Queues(0), Workers(0), Configs(0), Log(NULL), ToFetch(0), Debug(_config->FindB("Debug::pkgAcquire",false)), - Running(false), LockFD(-1) + Running(false) { string const Mode = _config->Find("Acquire::Queue-Mode","host"); if (strcasecmp(Mode.c_str(),"host") == 0) @@ -47,10 +47,10 @@ pkgAcquire::pkgAcquire() : Queues(0), Workers(0), Configs(0), Log(NULL), ToFetch if (strcasecmp(Mode.c_str(),"access") == 0) QueueMode = QueueAccess; } -pkgAcquire::pkgAcquire(pkgAcquireStatus *Progress) : Queues(0), Workers(0), +pkgAcquire::pkgAcquire(pkgAcquireStatus *Progress) : LockFD(-1), Queues(0), Workers(0), Configs(0), Log(Progress), ToFetch(0), Debug(_config->FindB("Debug::pkgAcquire",false)), - Running(false), LockFD(-1) + Running(false) { string const Mode = _config->Find("Acquire::Queue-Mode","host"); if (strcasecmp(Mode.c_str(),"host") == 0) @@ -799,7 +799,7 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner) } // Compute the current completion - unsigned long ResumeSize = 0; + unsigned long long ResumeSize = 0; for (pkgAcquire::Worker *I = Owner->WorkersBegin(); I != 0; I = Owner->WorkerStep(I)) if (I->CurrentItem != 0 && I->CurrentItem->Owner->Complete == false) @@ -838,7 +838,7 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner) else CurrentCPS = ((CurrentBytes - ResumeSize) - LastBytes)/Delta; LastBytes = CurrentBytes - ResumeSize; - ElapsedTime = (unsigned long)Delta; + ElapsedTime = (unsigned long long)Delta; Time = NewTime; } @@ -849,8 +849,9 @@ bool pkgAcquireStatus::Pulse(pkgAcquire *Owner) char msg[200]; long i = CurrentItems < TotalItems ? CurrentItems + 1 : CurrentItems; - unsigned long ETA = - (unsigned long)((TotalBytes - CurrentBytes) / CurrentCPS); + unsigned long long ETA = 0; + if(CurrentCPS > 0) + ETA = (TotalBytes - CurrentBytes) / CurrentCPS; // only show the ETA if it makes sense if (ETA > 0 && ETA < 172800 /* two days */ ) @@ -906,13 +907,13 @@ void pkgAcquireStatus::Stop() else CurrentCPS = FetchedBytes/Delta; LastBytes = CurrentBytes; - ElapsedTime = (unsigned int)Delta; + ElapsedTime = (unsigned long long)Delta; } /*}}}*/ // AcquireStatus::Fetched - Called when a byte set has been fetched /*{{{*/ // --------------------------------------------------------------------- /* This is used to get accurate final transfer rate reporting. */ -void pkgAcquireStatus::Fetched(unsigned long Size,unsigned long Resume) +void pkgAcquireStatus::Fetched(unsigned long long Size,unsigned long long Resume) { FetchedBytes += Size - Resume; } diff --git a/apt-pkg/acquire.h b/apt-pkg/acquire.h index 9fe0e8a87..ae555df22 100644 --- a/apt-pkg/acquire.h +++ b/apt-pkg/acquire.h @@ -91,6 +91,12 @@ class pkgAcquireStatus; */ class pkgAcquire { + private: + /** \brief FD of the Lock file we acquire in Setup (if any) */ + int LockFD; + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; + public: class Item; @@ -142,12 +148,7 @@ class pkgAcquire /** \brief The progress indicator for this download. */ pkgAcquireStatus *Log; - /** \brief The total size of the files which are to be fetched. - * - * This is not necessarily the total number of bytes to download - * when, e.g., download resumption and list updates via patches - * are taken into account. - */ + /** \brief The number of files which are to be fetched. */ unsigned long ToFetch; // Configurable parameters for the scheduler @@ -361,9 +362,6 @@ class pkgAcquire */ virtual ~pkgAcquire(); - private: - /** \brief FD of the Lock file we acquire in Setup (if any) */ - int LockFD; }; /** \brief Represents a single download source from which an item @@ -393,6 +391,9 @@ class pkgAcquire::Queue friend class pkgAcquire::UriIterator; friend class pkgAcquire::Worker; + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; + /** \brief The next queue in the pkgAcquire object's list of queues. */ Queue *Next; @@ -480,7 +481,7 @@ class pkgAcquire::Queue * * \todo Unimplemented. Implement it or remove? */ - bool ItemStart(QItem *Itm,unsigned long Size); + bool ItemStart(QItem *Itm,unsigned long long Size); /** \brief Remove the given item from this queue and set its state * to pkgAcquire::Item::StatDone. @@ -542,12 +543,15 @@ class pkgAcquire::Queue /** Shut down all the worker processes associated with this queue * and empty the queue. */ - ~Queue(); + virtual ~Queue(); }; /*}}}*/ /** \brief Iterates over all the URIs being fetched by a pkgAcquire object. {{{*/ class pkgAcquire::UriIterator { + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; + /** The next queue to iterate over. */ pkgAcquire::Queue *CurQ; /** The item that we currently point at. */ @@ -583,11 +587,15 @@ class pkgAcquire::UriIterator CurQ = CurQ->Next; } } + virtual ~UriIterator() {}; }; /*}}}*/ /** \brief Information about the properties of a single acquire method. {{{*/ struct pkgAcquire::MethodConfig { + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; + /** \brief The next link on the acquire method list. * * \todo Why not an STL container? @@ -636,16 +644,20 @@ struct pkgAcquire::MethodConfig * appropriate. */ MethodConfig(); + + /* \brief Destructor, empty currently */ + virtual ~MethodConfig() {}; }; /*}}}*/ /** \brief A monitor object for downloads controlled by the pkgAcquire class. {{{ * * \todo Why protected members? - * - * \todo Should the double members be uint64_t? */ class pkgAcquireStatus { + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; + protected: /** \brief The last time at which this monitor object was updated. */ @@ -657,34 +669,34 @@ class pkgAcquireStatus /** \brief The number of bytes fetched as of the previous call to * pkgAcquireStatus::Pulse, including local items. */ - double LastBytes; + unsigned long long LastBytes; /** \brief The current rate of download as of the most recent call * to pkgAcquireStatus::Pulse, in bytes per second. */ - double CurrentCPS; + unsigned long long CurrentCPS; /** \brief The number of bytes fetched as of the most recent call * to pkgAcquireStatus::Pulse, including local items. */ - double CurrentBytes; + unsigned long long CurrentBytes; /** \brief The total number of bytes that need to be fetched. * * \warning This member is inaccurate, as new items might be * enqueued while the download is in progress! */ - double TotalBytes; + unsigned long long TotalBytes; /** \brief The total number of bytes accounted for by items that * were successfully fetched. */ - double FetchedBytes; + unsigned long long FetchedBytes; /** \brief The amount of time that has elapsed since the download * started. */ - unsigned long ElapsedTime; + unsigned long long ElapsedTime; /** \brief The total number of items that need to be fetched. * @@ -717,7 +729,7 @@ class pkgAcquireStatus * * \param ResumePoint How much of the file was already fetched. */ - virtual void Fetched(unsigned long Size,unsigned long ResumePoint); + virtual void Fetched(unsigned long long Size,unsigned long long ResumePoint); /** \brief Invoked when the user should be prompted to change the * inserted removable media. diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 5fbcb47be..08d1f8cb7 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -20,12 +20,15 @@ #include <apt-pkg/version.h> #include <apt-pkg/sptr.h> #include <apt-pkg/acquire-item.h> - +#include <apt-pkg/edsp.h> + #include <apti18n.h> #include <sys/types.h> #include <cstdlib> #include <algorithm> #include <iostream> + +#include <stdio.h> /*}}}*/ using namespace std; @@ -327,6 +330,12 @@ bool pkgFixBroken(pkgDepCache &Cache) */ 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 @@ -379,6 +388,12 @@ bool pkgDistUpgrade(pkgDepCache &Cache) to install packages not marked for install */ bool pkgAllUpgrade(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); @@ -725,7 +740,20 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg) return true; } /*}}}*/ -// ProblemResolver::Resolve - Run the resolution pass /*{{{*/ +// ProblemResolver::Resolve - calls a resolver to fix the situation /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgProblemResolver::Resolve(bool BrokenFix) +{ + std::string const solver = _config->Find("APT::Solver", "internal"); + if (solver != "internal") { + OpTextProgress Prog(*_config); + return EDSP::ResolveExternal(solver.c_str(), Cache, false, false, false, &Prog); + } + return ResolveInternal(BrokenFix); +} + /*}}}*/ +// ProblemResolver::ResolveInternal - Run the resolution pass /*{{{*/ // --------------------------------------------------------------------- /* This routines works by calculating a score for each package. The score is derived by considering the package's priority and all reverse @@ -739,12 +767,10 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg) The BrokenFix flag enables a mode where the algorithm tries to upgrade packages to advoid problems. */ -bool pkgProblemResolver::Resolve(bool BrokenFix) +bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) { pkgDepCache::ActionGroup group(Cache); - unsigned long Size = Cache.Head().PackageCount; - // Record which packages are marked for install bool Again = false; do @@ -774,7 +800,9 @@ bool pkgProblemResolver::Resolve(bool BrokenFix) clog << "Starting" << endl; MakeScores(); - + + unsigned long const Size = Cache.Head().PackageCount; + /* We have to order the packages so that the broken fixing pass operates from highest score to lowest. This prevents problems when high score packages cause the removal of lower score packages that @@ -1208,6 +1236,21 @@ bool pkgProblemResolver::InstOrNewPolicyBroken(pkgCache::PkgIterator I) system was non-broken previously. */ bool pkgProblemResolver::ResolveByKeep() { + 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); + } + return ResolveByKeepInternal(); +} + /*}}}*/ +// ProblemResolver::ResolveByKeepInternal - Resolve problems using keep /*{{{*/ +// --------------------------------------------------------------------- +/* This is the work horse of the soft upgrade routine. It is very gental + in that it does not install or remove any packages. It is assumed that the + system was non-broken previously. */ +bool pkgProblemResolver::ResolveByKeepInternal() +{ pkgDepCache::ActionGroup group(Cache); unsigned long Size = Cache.Head().PackageCount; diff --git a/apt-pkg/algorithms.h b/apt-pkg/algorithms.h index 99501bed1..86d5fbd53 100644 --- a/apt-pkg/algorithms.h +++ b/apt-pkg/algorithms.h @@ -78,6 +78,9 @@ private: /*}}}*/ class pkgProblemResolver /*{{{*/ { + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; + pkgDepCache &Cache; typedef pkgCache::PkgIterator PkgIterator; typedef pkgCache::VerIterator VerIterator; @@ -105,6 +108,9 @@ class pkgProblemResolver /*{{{*/ void MakeScores(); bool DoUpgrade(pkgCache::PkgIterator Pkg); + + bool ResolveInternal(bool const BrokenFix = false); + bool ResolveByKeepInternal(); protected: bool InstOrNewPolicyBroken(pkgCache::PkgIterator Pkg); diff --git a/apt-pkg/cachefile.h b/apt-pkg/cachefile.h index 09d3ec267..d07337d38 100644 --- a/apt-pkg/cachefile.h +++ b/apt-pkg/cachefile.h @@ -25,6 +25,9 @@ class pkgCacheFile { + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; + protected: MMap *Map; diff --git a/apt-pkg/cachefilter.h b/apt-pkg/cachefilter.h index e7ab1723f..5d426008b 100644 --- a/apt-pkg/cachefilter.h +++ b/apt-pkg/cachefilter.h @@ -16,6 +16,8 @@ namespace APT { namespace CacheFilter { // PackageNameMatchesRegEx /*{{{*/ class PackageNameMatchesRegEx { + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; regex_t* pattern; public: PackageNameMatchesRegEx(std::string const &Pattern); diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h index 0c9813c6d..b97a1a589 100644 --- a/apt-pkg/cacheiterators.h +++ b/apt-pkg/cacheiterators.h @@ -206,15 +206,10 @@ class pkgCache::VerIterator : public Iterator<Version, VerIterator> { inline const char *VerStr() const {return S->VerStr == 0?0:Owner->StrP + S->VerStr;}; inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;}; inline const char *Arch() const { - if (S->MultiArch == pkgCache::Version::All || - S->MultiArch == pkgCache::Version::AllForeign || - S->MultiArch == pkgCache::Version::AllAllowed) + if (S->MultiArch == pkgCache::Version::All) return "all"; return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch; }; - __deprecated inline const char *Arch(bool const pseudo) const { - return S->ParentPkg == 0?0:Owner->StrP + ParentPkg()->Arch; - }; inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + S->ParentPkg);}; inline DescIterator DescriptionList() const; @@ -227,7 +222,6 @@ class pkgCache::VerIterator : public Iterator<Version, VerIterator> { string RelStr() const; bool Automatic() const; - __deprecated bool Pseudo() const; VerFileIterator NewestFile() const; inline VerIterator(pkgCache &Owner,Version *Trg = 0) : Iterator<Version, VerIterator>(Owner, Trg) { diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h index eb4f04d72..061d0a2f4 100644 --- a/apt-pkg/cacheset.h +++ b/apt-pkg/cacheset.h @@ -257,7 +257,6 @@ public: /*{{{*/ inline const char *VerStr() const { return (**this).VerStr(); }; inline const char *Section() const { return (**this).Section(); }; inline const char *Arch() const { return (**this).Arch(); }; - __deprecated inline const char *Arch(bool const pseudo) const { return (**this).Arch(); }; inline pkgCache::PkgIterator ParentPkg() const { return (**this).ParentPkg(); }; inline pkgCache::DescIterator DescriptionList() const { return (**this).DescriptionList(); }; inline pkgCache::DescIterator TranslatedDescription() const { return (**this).TranslatedDescription(); }; @@ -268,7 +267,6 @@ public: /*{{{*/ inline const char *PriorityType() const { return (**this).PriorityType(); }; inline string RelStr() const { return (**this).RelStr(); }; inline bool Automatic() const { return (**this).Automatic(); }; - __deprecated inline bool Pseudo() const { return false; }; inline pkgCache::VerFileIterator NewestFile() const { return (**this).NewestFile(); }; }; /*}}}*/ diff --git a/apt-pkg/cdrom.cc b/apt-pkg/cdrom.cc index b8acf0cbe..df1ffedf2 100644 --- a/apt-pkg/cdrom.cc +++ b/apt-pkg/cdrom.cc @@ -874,9 +874,7 @@ pkgUdevCdromDevices::Dlopen() /*{{{*/ libudev_handle = h; udev_new = (udev* (*)(void)) dlsym(h, "udev_new"); udev_enumerate_add_match_property = (int (*)(udev_enumerate*, const char*, const char*))dlsym(h, "udev_enumerate_add_match_property"); -#if 0 // FIXME: uncomment on next ABI break udev_enumerate_add_match_sysattr = (int (*)(udev_enumerate*, const char*, const char*))dlsym(h, "udev_enumerate_add_match_sysattr"); -#endif udev_enumerate_scan_devices = (int (*)(udev_enumerate*))dlsym(h, "udev_enumerate_scan_devices"); udev_enumerate_get_list_entry = (udev_list_entry* (*)(udev_enumerate*))dlsym(h, "udev_enumerate_get_list_entry"); udev_device_new_from_syspath = (udev_device* (*)(udev*, const char*))dlsym(h, "udev_device_new_from_syspath"); @@ -890,10 +888,8 @@ pkgUdevCdromDevices::Dlopen() /*{{{*/ return true; } /*}}}*/ - /*{{{*/ -// compatiblity only with the old API/ABI, can be removed on the next -// ABI break +// convenience interface, this will just call ScanForRemovable vector<CdromDevice> pkgUdevCdromDevices::Scan() { @@ -918,10 +914,6 @@ pkgUdevCdromDevices::ScanForRemovable(bool CdromOnly) if (CdromOnly) udev_enumerate_add_match_property(enumerate, "ID_CDROM", "1"); else { -#if 1 // FIXME: remove the next two lines on the next ABI break - int (*udev_enumerate_add_match_sysattr)(struct udev_enumerate *udev_enumerate, const char *property, const char *value); - udev_enumerate_add_match_sysattr = (int (*)(udev_enumerate*, const char*, const char*))dlsym(libudev_handle, "udev_enumerate_add_match_sysattr"); -#endif udev_enumerate_add_match_sysattr(enumerate, "removable", "1"); } diff --git a/apt-pkg/cdrom.h b/apt-pkg/cdrom.h index e83c38582..614062cbb 100644 --- a/apt-pkg/cdrom.h +++ b/apt-pkg/cdrom.h @@ -92,9 +92,7 @@ class pkgUdevCdromDevices /*{{{*/ struct udev_enumerate *(*udev_enumerate_new) (struct udev *udev); struct udev_list_entry *(*udev_list_entry_get_next)(struct udev_list_entry *list_entry); const char* (*udev_device_get_property_value)(struct udev_device *udev_device, const char *key); -#if 0 // FIXME: uncomment on next ABI break int (*udev_enumerate_add_match_sysattr)(struct udev_enumerate *udev_enumerate, const char *property, const char *value); -#endif // end libudev dlopen public: @@ -104,11 +102,11 @@ class pkgUdevCdromDevices /*{{{*/ // try to open bool Dlopen(); - // this is the new interface - vector<CdromDevice> ScanForRemovable(bool CdromOnly); - // FIXME: compat with the old interface/API/ABI only + // convenience interface, this will just call ScanForRemovable + // with "APT::cdrom::CdromOnly" vector<CdromDevice> Scan(); + vector<CdromDevice> ScanForRemovable(bool CdromOnly); }; /*}}}*/ diff --git a/apt-pkg/clean.h b/apt-pkg/clean.h index 2aee2bf54..1ebf68dc9 100644 --- a/apt-pkg/clean.h +++ b/apt-pkg/clean.h @@ -15,6 +15,9 @@ class pkgArchiveCleaner { + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; + protected: virtual void Erase(const char * /*File*/,string /*Pkg*/,string /*Ver*/,struct stat & /*St*/) {}; diff --git a/apt-pkg/contrib/hashes.cc b/apt-pkg/contrib/hashes.cc index 985d89d90..4407574fa 100644 --- a/apt-pkg/contrib/hashes.cc +++ b/apt-pkg/contrib/hashes.cc @@ -23,7 +23,7 @@ const char* HashString::_SupportedHashes[] = { - "SHA256", "SHA1", "MD5Sum", NULL + "SHA512", "SHA256", "SHA1", "MD5Sum", NULL }; HashString::HashString() @@ -53,28 +53,33 @@ HashString::HashString(string StringedHash) /*{{{*/ /*}}}*/ bool HashString::VerifyFile(string filename) const /*{{{*/ { - FileFd fd; - MD5Summation MD5; - SHA1Summation SHA1; - SHA256Summation SHA256; string fileHash; FileFd Fd(filename, FileFd::ReadOnly); - if(Type == "MD5Sum") + if(Type == "MD5Sum") { + MD5Summation MD5; MD5.AddFD(Fd.Fd(), Fd.Size()); fileHash = (string)MD5.Result(); - } + } else if (Type == "SHA1") { + SHA1Summation SHA1; SHA1.AddFD(Fd.Fd(), Fd.Size()); fileHash = (string)SHA1.Result(); - } - else if (Type == "SHA256") + } + else if (Type == "SHA256") { + SHA256Summation SHA256; SHA256.AddFD(Fd.Fd(), Fd.Size()); fileHash = (string)SHA256.Result(); } + else if (Type == "SHA512") + { + SHA512Summation SHA512; + SHA512.AddFD(Fd.Fd(), Fd.Size()); + fileHash = (string)SHA512.Result(); + } Fd.Close(); if(_config->FindB("Debug::Hashes",false) == true) @@ -101,7 +106,8 @@ string HashString::toStr() const // Hashes::AddFD - Add the contents of the FD /*{{{*/ // --------------------------------------------------------------------- /* */ -bool Hashes::AddFD(int Fd,unsigned long Size) +bool Hashes::AddFD(int const Fd,unsigned long Size, bool const addMD5, + bool const addSHA1, bool const addSHA256, bool const addSHA512) { unsigned char Buf[64*64]; int Res = 0; @@ -112,13 +118,18 @@ bool Hashes::AddFD(int Fd,unsigned long Size) if (!ToEOF) n = min(Size,(unsigned long)n); Res = read(Fd,Buf,n); if (Res < 0 || (!ToEOF && (unsigned) Res != n)) // error, or short read - return false; + return false; if (ToEOF && Res == 0) // EOF - break; + break; Size -= Res; - MD5.Add(Buf,Res); - SHA1.Add(Buf,Res); - SHA256.Add(Buf,Res); + if (addMD5 == true) + MD5.Add(Buf,Res); + if (addSHA1 == true) + SHA1.Add(Buf,Res); + if (addSHA256 == true) + SHA256.Add(Buf,Res); + if (addSHA512 == true) + SHA512.Add(Buf,Res); } return true; } diff --git a/apt-pkg/contrib/hashes.h b/apt-pkg/contrib/hashes.h index 264f7fe90..e702fcca2 100644 --- a/apt-pkg/contrib/hashes.h +++ b/apt-pkg/contrib/hashes.h @@ -16,7 +16,7 @@ #include <apt-pkg/md5.h> #include <apt-pkg/sha1.h> -#include <apt-pkg/sha256.h> +#include <apt-pkg/sha2.h> #include <algorithm> #include <vector> @@ -60,13 +60,17 @@ class Hashes MD5Summation MD5; SHA1Summation SHA1; SHA256Summation SHA256; + SHA512Summation SHA512; inline bool Add(const unsigned char *Data,unsigned long Size) { - return MD5.Add(Data,Size) && SHA1.Add(Data,Size) && SHA256.Add(Data,Size); + return MD5.Add(Data,Size) && SHA1.Add(Data,Size) && SHA256.Add(Data,Size) && SHA512.Add(Data,Size); }; inline bool Add(const char *Data) {return Add((unsigned char *)Data,strlen(Data));}; - bool AddFD(int Fd,unsigned long Size); + inline bool AddFD(int const Fd,unsigned long Size = 0) + { return AddFD(Fd, Size, true, true, true, true); }; + bool AddFD(int const Fd, unsigned long Size, bool const addMD5, + bool const addSHA1, bool const addSHA256, bool const addSHA512); inline bool Add(const unsigned char *Beg,const unsigned char *End) {return Add(Beg,End-Beg);}; }; diff --git a/apt-pkg/contrib/hashsum.cc b/apt-pkg/contrib/hashsum.cc new file mode 100644 index 000000000..728747d7a --- /dev/null +++ b/apt-pkg/contrib/hashsum.cc @@ -0,0 +1,27 @@ +// Cryptographic API Base + +#include <unistd.h> +#include "hashsum_template.h" + +// Summation::AddFD - Add content of file into the checksum /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool SummationImplementation::AddFD(int const Fd, unsigned long Size) { + unsigned char Buf[64 * 64]; + int Res = 0; + int ToEOF = (Size == 0); + while (Size != 0 || ToEOF) + { + unsigned n = sizeof(Buf); + if (!ToEOF) n = min(Size,(unsigned long)n); + Res = read(Fd, Buf, n); + if (Res < 0 || (!ToEOF && (unsigned) Res != n)) // error, or short read + return false; + if (ToEOF && Res == 0) // EOF + break; + Size -= Res; + Add(Buf,Res); + } + return true; +} + /*}}}*/ diff --git a/apt-pkg/contrib/hashsum_template.h b/apt-pkg/contrib/hashsum_template.h new file mode 100644 index 000000000..85d94c2af --- /dev/null +++ b/apt-pkg/contrib/hashsum_template.h @@ -0,0 +1,107 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: hashsum_template.h,v 1.3 2001/05/07 05:05:47 jgg Exp $ +/* ###################################################################### + + HashSumValueTemplate - Generic Storage for a hash value + + ##################################################################### */ + /*}}}*/ +#ifndef APTPKG_HASHSUM_TEMPLATE_H +#define APTPKG_HASHSUM_TEMPLATE_H + +#include <string> +#include <cstring> +#include <algorithm> +#include <stdint.h> + +using std::string; +using std::min; + +template<int N> +class HashSumValue +{ + unsigned char Sum[N/8]; + + public: + + // Accessors + bool operator ==(const HashSumValue &rhs) const + { + return memcmp(Sum,rhs.Sum,sizeof(Sum)) == 0; + }; + + string Value() const + { + char Conv[16] = + { '0','1','2','3','4','5','6','7','8','9','a','b', + 'c','d','e','f' + }; + char Result[((N/8)*2)+1]; + Result[(N/8)*2] = 0; + + // Convert each char into two letters + int J = 0; + int I = 0; + for (; I != (N/8)*2; J++,I += 2) + { + Result[I] = Conv[Sum[J] >> 4]; + Result[I + 1] = Conv[Sum[J] & 0xF]; + } + return string(Result); + }; + + inline void Value(unsigned char S[N/8]) + { + for (int I = 0; I != sizeof(Sum); I++) + S[I] = Sum[I]; + }; + + inline operator string() const + { + return Value(); + }; + + bool Set(string Str) + { + return Hex2Num(Str,Sum,sizeof(Sum)); + }; + + inline void Set(unsigned char S[N/8]) + { + for (int I = 0; I != sizeof(Sum); I++) + Sum[I] = S[I]; + }; + + HashSumValue(string Str) + { + memset(Sum,0,sizeof(Sum)); + Set(Str); + } + HashSumValue() + { + memset(Sum,0,sizeof(Sum)); + } +}; + +class SummationImplementation +{ + public: + virtual bool Add(const unsigned char *inbuf, unsigned long inlen) = 0; + inline bool Add(const char *inbuf, unsigned long const inlen) + { return Add((unsigned char *)inbuf, inlen); }; + + inline bool Add(const unsigned char *Data) + { return Add(Data, strlen((const char *)Data)); }; + inline bool Add(const char *Data) + { return Add((const unsigned char *)Data, strlen((const char *)Data)); }; + + inline bool Add(const unsigned char *Beg, const unsigned char *End) + { return Add(Beg, End - Beg); }; + inline bool Add(const char *Beg, const char *End) + { return Add((const unsigned char *)Beg, End - Beg); }; + + bool AddFD(int Fd, unsigned long Size = 0); +}; + +#endif diff --git a/apt-pkg/contrib/md5.cc b/apt-pkg/contrib/md5.cc index c0fa8493d..65e20e9bb 100644 --- a/apt-pkg/contrib/md5.cc +++ b/apt-pkg/contrib/md5.cc @@ -165,61 +165,6 @@ static void MD5Transform(uint32_t buf[4], uint32_t const in[16]) buf[3] += d; } /*}}}*/ -// MD5SumValue::MD5SumValue - Constructs the summation from a string /*{{{*/ -// --------------------------------------------------------------------- -/* The string form of a MD5 is a 32 character hex number */ -MD5SumValue::MD5SumValue(string Str) -{ - memset(Sum,0,sizeof(Sum)); - Set(Str); -} - /*}}}*/ -// MD5SumValue::MD5SumValue - Default constructor /*{{{*/ -// --------------------------------------------------------------------- -/* Sets the value to 0 */ -MD5SumValue::MD5SumValue() -{ - memset(Sum,0,sizeof(Sum)); -} - /*}}}*/ -// MD5SumValue::Set - Set the sum from a string /*{{{*/ -// --------------------------------------------------------------------- -/* Converts the hex string into a set of chars */ -bool MD5SumValue::Set(string Str) -{ - return Hex2Num(Str,Sum,sizeof(Sum)); -} - /*}}}*/ -// MD5SumValue::Value - Convert the number into a string /*{{{*/ -// --------------------------------------------------------------------- -/* Converts the set of chars into a hex string in lower case */ -string MD5SumValue::Value() const -{ - char Conv[16] = {'0','1','2','3','4','5','6','7','8','9','a','b', - 'c','d','e','f'}; - char Result[33]; - Result[32] = 0; - - // Convert each char into two letters - int J = 0; - int I = 0; - for (; I != 32; J++, I += 2) - { - Result[I] = Conv[Sum[J] >> 4]; - Result[I + 1] = Conv[Sum[J] & 0xF]; - } - - return string(Result); -} - /*}}}*/ -// MD5SumValue::operator == - Comparitor /*{{{*/ -// --------------------------------------------------------------------- -/* Call memcmp on the buffer */ -bool MD5SumValue::operator ==(const MD5SumValue &rhs) const -{ - return memcmp(Sum,rhs.Sum,sizeof(Sum)) == 0; -} - /*}}}*/ // MD5Summation::MD5Summation - Initialize the summer /*{{{*/ // --------------------------------------------------------------------- /* This assigns the deep magic initial values */ @@ -286,29 +231,6 @@ bool MD5Summation::Add(const unsigned char *data,unsigned long len) return true; } /*}}}*/ -// MD5Summation::AddFD - Add the contents of a FD to the hash /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool MD5Summation::AddFD(int Fd,unsigned long Size) -{ - unsigned char Buf[64*64]; - int Res = 0; - int ToEOF = (Size == 0); - while (Size != 0 || ToEOF) - { - unsigned n = sizeof(Buf); - if (!ToEOF) n = min(Size,(unsigned long)n); - Res = read(Fd,Buf,n); - if (Res < 0 || (!ToEOF && (unsigned) Res != n)) // error, or short read - return false; - if (ToEOF && Res == 0) // EOF - break; - Size -= Res; - Add(Buf,Res); - } - return true; -} - /*}}}*/ // MD5Summation::Result - Returns the value of the sum /*{{{*/ // --------------------------------------------------------------------- /* Because this must add in the last bytes of the series it prevents anyone @@ -353,7 +275,7 @@ MD5SumValue MD5Summation::Result() } MD5SumValue V; - memcpy(V.Sum,buf,16); + V.Set((unsigned char *)buf); return V; } /*}}}*/ diff --git a/apt-pkg/contrib/md5.h b/apt-pkg/contrib/md5.h index 96c8975b4..e76428325 100644 --- a/apt-pkg/contrib/md5.h +++ b/apt-pkg/contrib/md5.h @@ -32,45 +32,24 @@ using std::string; using std::min; -class MD5Summation; +#include "hashsum_template.h" -class MD5SumValue -{ - friend class MD5Summation; - unsigned char Sum[4*4]; - - public: - - // Accessors - bool operator ==(const MD5SumValue &rhs) const; - string Value() const; - inline void Value(unsigned char S[16]) - {for (int I = 0; I != sizeof(Sum); I++) S[I] = Sum[I];}; - inline operator string() const {return Value();}; - bool Set(string Str); - inline void Set(unsigned char S[16]) - {for (int I = 0; I != sizeof(Sum); I++) Sum[I] = S[I];}; - - MD5SumValue(string Str); - MD5SumValue(); -}; +typedef HashSumValue<128> MD5SumValue; -class MD5Summation +class MD5Summation : public SummationImplementation { uint32_t Buf[4]; unsigned char Bytes[2*4]; unsigned char In[16*4]; bool Done; - + public: - bool Add(const unsigned char *Data,unsigned long Size); - inline bool Add(const char *Data) {return Add((unsigned char *)Data,strlen(Data));}; - bool AddFD(int Fd,unsigned long Size); - inline bool Add(const unsigned char *Beg,const unsigned char *End) - {return Add(Beg,End-Beg);}; + bool Add(const unsigned char *inbuf, unsigned long inlen); + using SummationImplementation::Add; + MD5SumValue Result(); - + MD5Summation(); }; diff --git a/apt-pkg/contrib/progress.cc b/apt-pkg/contrib/progress.cc index 45e81edcb..84ee4c124 100644 --- a/apt-pkg/contrib/progress.cc +++ b/apt-pkg/contrib/progress.cc @@ -65,27 +65,18 @@ void OpProgress::OverallProgress(unsigned long Current, unsigned long Total, // OpProgress::SubProgress - Set the sub progress state /*{{{*/ // --------------------------------------------------------------------- /* */ -void OpProgress::SubProgress(unsigned long SubTotal,const string &Op) +void OpProgress::SubProgress(unsigned long SubTotal,const string &Op, + float const Percent) { this->SubTotal = SubTotal; - SubOp = Op; - if (Total == 0) - Percent = 0; + if (Op.empty() == false) + SubOp = Op; + if (Total == 0 || Percent == 0) + this->Percent = 0; + else if (Percent != -1) + this->Percent = this->Current += (Size*Percent)/SubTotal; else - Percent = Current*100.0/Total; - Update(); -} - /*}}}*/ -// OpProgress::SubProgress - Set the sub progress state /*{{{*/ -// --------------------------------------------------------------------- -/* */ -void OpProgress::SubProgress(unsigned long SubTotal) -{ - this->SubTotal = SubTotal; - if (Total == 0) - Percent = 0; - else - Percent = Current*100.0/Total; + this->Percent = Current*100.0/Total; Update(); } /*}}}*/ diff --git a/apt-pkg/contrib/progress.h b/apt-pkg/contrib/progress.h index 7dd004f7e..3a914d17f 100644 --- a/apt-pkg/contrib/progress.h +++ b/apt-pkg/contrib/progress.h @@ -55,8 +55,7 @@ class OpProgress public: void Progress(unsigned long Current); - void SubProgress(unsigned long SubTotal); - void SubProgress(unsigned long SubTotal,const string &Op); + void SubProgress(unsigned long SubTotal, const string &Op = "", float const Percent = -1); void OverallProgress(unsigned long Current,unsigned long Total, unsigned long Size,const string &Op); virtual void Done() {}; diff --git a/apt-pkg/contrib/sha1.cc b/apt-pkg/contrib/sha1.cc index abc2aaf9f..5b9db202d 100644 --- a/apt-pkg/contrib/sha1.cc +++ b/apt-pkg/contrib/sha1.cc @@ -177,67 +177,6 @@ static void SHA1Transform(uint32_t state[5],uint8_t const buffer[64]) } /*}}}*/ -// SHA1SumValue::SHA1SumValue - Constructs the summation from a string /*{{{*/ -// --------------------------------------------------------------------- -/* The string form of a SHA1 is a 40 character hex number */ -SHA1SumValue::SHA1SumValue(string Str) -{ - memset(Sum,0,sizeof(Sum)); - Set(Str); -} - - /*}}} */ -// SHA1SumValue::SHA1SumValue - Default constructor /*{{{*/ -// --------------------------------------------------------------------- -/* Sets the value to 0 */ -SHA1SumValue::SHA1SumValue() -{ - memset(Sum,0,sizeof(Sum)); -} - - /*}}} */ -// SHA1SumValue::Set - Set the sum from a string /*{{{*/ -// --------------------------------------------------------------------- -/* Converts the hex string into a set of chars */ -bool SHA1SumValue::Set(string Str) -{ - return Hex2Num(Str,Sum,sizeof(Sum)); -} - - /*}}} */ -// SHA1SumValue::Value - Convert the number into a string /*{{{*/ -// --------------------------------------------------------------------- -/* Converts the set of chars into a hex string in lower case */ -string SHA1SumValue::Value() const -{ - char Conv[16] = - { '0','1','2','3','4','5','6','7','8','9','a','b', - 'c','d','e','f' - }; - char Result[41]; - Result[40] = 0; - - // Convert each char into two letters - int J = 0; - int I = 0; - for (; I != 40; J++,I += 2) - { - Result[I] = Conv[Sum[J] >> 4]; - Result[I + 1] = Conv[Sum[J] & 0xF]; - } - - return string(Result); -} - - /*}}} */ -// SHA1SumValue::operator == - Comparator /*{{{*/ -// --------------------------------------------------------------------- -/* Call memcmp on the buffer */ -bool SHA1SumValue::operator == (const SHA1SumValue & rhs) const -{ - return memcmp(Sum,rhs.Sum,sizeof(Sum)) == 0; -} - /*}}}*/ // SHA1Summation::SHA1Summation - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -289,11 +228,13 @@ SHA1SumValue SHA1Summation::Result() // Transfer over the result SHA1SumValue Value; + unsigned char res[20]; for (unsigned i = 0; i < 20; i++) { - Value.Sum[i] = (unsigned char) + res[i] = (unsigned char) ((state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); } + Value.Set(res); return Value; } /*}}}*/ @@ -331,26 +272,3 @@ bool SHA1Summation::Add(const unsigned char *data,unsigned long len) return true; } /*}}}*/ -// SHA1Summation::AddFD - Add content of file into the checksum /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool SHA1Summation::AddFD(int Fd,unsigned long Size) -{ - unsigned char Buf[64 * 64]; - int Res = 0; - int ToEOF = (Size == 0); - while (Size != 0 || ToEOF) - { - unsigned n = sizeof(Buf); - if (!ToEOF) n = min(Size,(unsigned long)n); - Res = read(Fd,Buf,n); - if (Res < 0 || (!ToEOF && (unsigned) Res != n)) // error, or short read - return false; - if (ToEOF && Res == 0) // EOF - break; - Size -= Res; - Add(Buf,Res); - } - return true; -} - /*}}}*/ diff --git a/apt-pkg/contrib/sha1.h b/apt-pkg/contrib/sha1.h index 8ddd889f1..2701fc67e 100644 --- a/apt-pkg/contrib/sha1.h +++ b/apt-pkg/contrib/sha1.h @@ -21,30 +21,11 @@ using std::string; using std::min; -class SHA1Summation; +#include "hashsum_template.h" -class SHA1SumValue -{ - friend class SHA1Summation; - unsigned char Sum[20]; - - public: - - // Accessors - bool operator ==(const SHA1SumValue &rhs) const; - string Value() const; - inline void Value(unsigned char S[20]) - {for (int I = 0; I != sizeof(Sum); I++) S[I] = Sum[I];}; - inline operator string() const {return Value();}; - bool Set(string Str); - inline void Set(unsigned char S[20]) - {for (int I = 0; I != sizeof(Sum); I++) Sum[I] = S[I];}; - - SHA1SumValue(string Str); - SHA1SumValue(); -}; +typedef HashSumValue<160> SHA1SumValue; -class SHA1Summation +class SHA1Summation : public SummationImplementation { /* assumes 64-bit alignment just in case */ unsigned char Buffer[64] __attribute__((aligned(8))); @@ -53,12 +34,9 @@ class SHA1Summation bool Done; public: + bool Add(const unsigned char *inbuf, unsigned long inlen); + using SummationImplementation::Add; - bool Add(const unsigned char *inbuf,unsigned long inlen); - inline bool Add(const char *Data) {return Add((unsigned char *)Data,strlen(Data));}; - bool AddFD(int Fd,unsigned long Size); - inline bool Add(const unsigned char *Beg,const unsigned char *End) - {return Add(Beg,End-Beg);}; SHA1SumValue Result(); SHA1Summation(); diff --git a/apt-pkg/contrib/sha2.h b/apt-pkg/contrib/sha2.h new file mode 100644 index 000000000..386225889 --- /dev/null +++ b/apt-pkg/contrib/sha2.h @@ -0,0 +1,103 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: sha512.h,v 1.3 2001/05/07 05:05:47 jgg Exp $ +/* ###################################################################### + + SHA{512,256}SumValue - Storage for a SHA-{512,256} hash. + SHA{512,256}Summation - SHA-{512,256} Secure Hash Algorithm. + + This is a C++ interface to a set of SHA{512,256}Sum functions, that mirrors + the equivalent MD5 & SHA1 classes. + + ##################################################################### */ + /*}}}*/ +#ifndef APTPKG_SHA2_H +#define APTPKG_SHA2_H + +#include <string> +#include <cstring> +#include <algorithm> +#include <stdint.h> + +#include "sha2_internal.h" +#include "hashsum_template.h" + +typedef HashSumValue<512> SHA512SumValue; +typedef HashSumValue<256> SHA256SumValue; + +class SHA2SummationBase : public SummationImplementation +{ + protected: + bool Done; + public: + bool Add(const unsigned char *inbuf, unsigned long len) = 0; + + void Result(); +}; + +class SHA256Summation : public SHA2SummationBase +{ + SHA256_CTX ctx; + unsigned char Sum[32]; + + public: + bool Add(const unsigned char *inbuf, unsigned long len) + { + if (Done) + return false; + SHA256_Update(&ctx, inbuf, len); + return true; + }; + using SummationImplementation::Add; + + SHA256SumValue Result() + { + if (!Done) { + SHA256_Final(Sum, &ctx); + Done = true; + } + SHA256SumValue res; + res.Set(Sum); + return res; + }; + SHA256Summation() + { + SHA256_Init(&ctx); + Done = false; + }; +}; + +class SHA512Summation : public SHA2SummationBase +{ + SHA512_CTX ctx; + unsigned char Sum[64]; + + public: + bool Add(const unsigned char *inbuf, unsigned long len) + { + if (Done) + return false; + SHA512_Update(&ctx, inbuf, len); + return true; + }; + using SummationImplementation::Add; + + SHA512SumValue Result() + { + if (!Done) { + SHA512_Final(Sum, &ctx); + Done = true; + } + SHA512SumValue res; + res.Set(Sum); + return res; + }; + SHA512Summation() + { + SHA512_Init(&ctx); + Done = false; + }; +}; + + +#endif diff --git a/apt-pkg/contrib/sha256.cc b/apt-pkg/contrib/sha256.cc deleted file mode 100644 index e380c13ae..000000000 --- a/apt-pkg/contrib/sha256.cc +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Cryptographic API. {{{ - * - * SHA-256, as specified in - * http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf - * - * SHA-256 code by Jean-Luc Cooke <jlcooke@certainkey.com>. - * - * Copyright (c) Jean-Luc Cooke <jlcooke@certainkey.com> - * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk> - * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> - * - * Ported from the Linux kernel to Apt by Anthony Towns <ajt@debian.org> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - */ /*}}}*/ - -#ifdef __GNUG__ -#pragma implementation "apt-pkg/sha256.h" -#endif - - -#define SHA256_DIGEST_SIZE 32 -#define SHA256_HMAC_BLOCK_SIZE 64 - -#define ror32(value,bits) (((value) >> (bits)) | ((value) << (32 - (bits)))) - -#include <apt-pkg/sha256.h> -#include <apt-pkg/strutl.h> -#include <string.h> -#include <unistd.h> -#include <stdint.h> -#include <stdlib.h> -#include <stdio.h> -#include <arpa/inet.h> - -typedef uint32_t u32; -typedef uint8_t u8; - -static inline u32 Ch(u32 x, u32 y, u32 z) -{ - return z ^ (x & (y ^ z)); -} - -static inline u32 Maj(u32 x, u32 y, u32 z) -{ - return (x & y) | (z & (x | y)); -} - -#define e0(x) (ror32(x, 2) ^ ror32(x,13) ^ ror32(x,22)) -#define e1(x) (ror32(x, 6) ^ ror32(x,11) ^ ror32(x,25)) -#define s0(x) (ror32(x, 7) ^ ror32(x,18) ^ (x >> 3)) -#define s1(x) (ror32(x,17) ^ ror32(x,19) ^ (x >> 10)) - -#define H0 0x6a09e667 -#define H1 0xbb67ae85 -#define H2 0x3c6ef372 -#define H3 0xa54ff53a -#define H4 0x510e527f -#define H5 0x9b05688c -#define H6 0x1f83d9ab -#define H7 0x5be0cd19 - -static inline void LOAD_OP(int I, u32 *W, const u8 *input) /*{{{*/ -{ - W[I] = ( ((u32) input[I * 4 + 0] << 24) - | ((u32) input[I * 4 + 1] << 16) - | ((u32) input[I * 4 + 2] << 8) - | ((u32) input[I * 4 + 3])); -} - /*}}}*/ -static inline void BLEND_OP(int I, u32 *W) -{ - W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16]; -} - -static void sha256_transform(u32 *state, const u8 *input) /*{{{*/ -{ - u32 a, b, c, d, e, f, g, h, t1, t2; - u32 W[64]; - int i; - - /* load the input */ - for (i = 0; i < 16; i++) - LOAD_OP(i, W, input); - - /* now blend */ - for (i = 16; i < 64; i++) - BLEND_OP(i, W); - - /* load the state into our registers */ - a=state[0]; b=state[1]; c=state[2]; d=state[3]; - e=state[4]; f=state[5]; g=state[6]; h=state[7]; - - /* now iterate */ - t1 = h + e1(e) + Ch(e,f,g) + 0x428a2f98 + W[ 0]; - t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; - t1 = g + e1(d) + Ch(d,e,f) + 0x71374491 + W[ 1]; - t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; - t1 = f + e1(c) + Ch(c,d,e) + 0xb5c0fbcf + W[ 2]; - t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; - t1 = e + e1(b) + Ch(b,c,d) + 0xe9b5dba5 + W[ 3]; - t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; - t1 = d + e1(a) + Ch(a,b,c) + 0x3956c25b + W[ 4]; - t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; - t1 = c + e1(h) + Ch(h,a,b) + 0x59f111f1 + W[ 5]; - t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; - t1 = b + e1(g) + Ch(g,h,a) + 0x923f82a4 + W[ 6]; - t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; - t1 = a + e1(f) + Ch(f,g,h) + 0xab1c5ed5 + W[ 7]; - t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; - - t1 = h + e1(e) + Ch(e,f,g) + 0xd807aa98 + W[ 8]; - t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; - t1 = g + e1(d) + Ch(d,e,f) + 0x12835b01 + W[ 9]; - t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; - t1 = f + e1(c) + Ch(c,d,e) + 0x243185be + W[10]; - t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; - t1 = e + e1(b) + Ch(b,c,d) + 0x550c7dc3 + W[11]; - t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; - t1 = d + e1(a) + Ch(a,b,c) + 0x72be5d74 + W[12]; - t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; - t1 = c + e1(h) + Ch(h,a,b) + 0x80deb1fe + W[13]; - t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; - t1 = b + e1(g) + Ch(g,h,a) + 0x9bdc06a7 + W[14]; - t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; - t1 = a + e1(f) + Ch(f,g,h) + 0xc19bf174 + W[15]; - t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; - - t1 = h + e1(e) + Ch(e,f,g) + 0xe49b69c1 + W[16]; - t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; - t1 = g + e1(d) + Ch(d,e,f) + 0xefbe4786 + W[17]; - t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; - t1 = f + e1(c) + Ch(c,d,e) + 0x0fc19dc6 + W[18]; - t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; - t1 = e + e1(b) + Ch(b,c,d) + 0x240ca1cc + W[19]; - t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; - t1 = d + e1(a) + Ch(a,b,c) + 0x2de92c6f + W[20]; - t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; - t1 = c + e1(h) + Ch(h,a,b) + 0x4a7484aa + W[21]; - t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; - t1 = b + e1(g) + Ch(g,h,a) + 0x5cb0a9dc + W[22]; - t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; - t1 = a + e1(f) + Ch(f,g,h) + 0x76f988da + W[23]; - t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; - - t1 = h + e1(e) + Ch(e,f,g) + 0x983e5152 + W[24]; - t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; - t1 = g + e1(d) + Ch(d,e,f) + 0xa831c66d + W[25]; - t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; - t1 = f + e1(c) + Ch(c,d,e) + 0xb00327c8 + W[26]; - t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; - t1 = e + e1(b) + Ch(b,c,d) + 0xbf597fc7 + W[27]; - t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; - t1 = d + e1(a) + Ch(a,b,c) + 0xc6e00bf3 + W[28]; - t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; - t1 = c + e1(h) + Ch(h,a,b) + 0xd5a79147 + W[29]; - t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; - t1 = b + e1(g) + Ch(g,h,a) + 0x06ca6351 + W[30]; - t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; - t1 = a + e1(f) + Ch(f,g,h) + 0x14292967 + W[31]; - t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; - - t1 = h + e1(e) + Ch(e,f,g) + 0x27b70a85 + W[32]; - t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; - t1 = g + e1(d) + Ch(d,e,f) + 0x2e1b2138 + W[33]; - t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; - t1 = f + e1(c) + Ch(c,d,e) + 0x4d2c6dfc + W[34]; - t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; - t1 = e + e1(b) + Ch(b,c,d) + 0x53380d13 + W[35]; - t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; - t1 = d + e1(a) + Ch(a,b,c) + 0x650a7354 + W[36]; - t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; - t1 = c + e1(h) + Ch(h,a,b) + 0x766a0abb + W[37]; - t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; - t1 = b + e1(g) + Ch(g,h,a) + 0x81c2c92e + W[38]; - t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; - t1 = a + e1(f) + Ch(f,g,h) + 0x92722c85 + W[39]; - t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; - - t1 = h + e1(e) + Ch(e,f,g) + 0xa2bfe8a1 + W[40]; - t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; - t1 = g + e1(d) + Ch(d,e,f) + 0xa81a664b + W[41]; - t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; - t1 = f + e1(c) + Ch(c,d,e) + 0xc24b8b70 + W[42]; - t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; - t1 = e + e1(b) + Ch(b,c,d) + 0xc76c51a3 + W[43]; - t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; - t1 = d + e1(a) + Ch(a,b,c) + 0xd192e819 + W[44]; - t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; - t1 = c + e1(h) + Ch(h,a,b) + 0xd6990624 + W[45]; - t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; - t1 = b + e1(g) + Ch(g,h,a) + 0xf40e3585 + W[46]; - t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; - t1 = a + e1(f) + Ch(f,g,h) + 0x106aa070 + W[47]; - t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; - - t1 = h + e1(e) + Ch(e,f,g) + 0x19a4c116 + W[48]; - t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; - t1 = g + e1(d) + Ch(d,e,f) + 0x1e376c08 + W[49]; - t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; - t1 = f + e1(c) + Ch(c,d,e) + 0x2748774c + W[50]; - t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; - t1 = e + e1(b) + Ch(b,c,d) + 0x34b0bcb5 + W[51]; - t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; - t1 = d + e1(a) + Ch(a,b,c) + 0x391c0cb3 + W[52]; - t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; - t1 = c + e1(h) + Ch(h,a,b) + 0x4ed8aa4a + W[53]; - t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; - t1 = b + e1(g) + Ch(g,h,a) + 0x5b9cca4f + W[54]; - t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; - t1 = a + e1(f) + Ch(f,g,h) + 0x682e6ff3 + W[55]; - t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; - - t1 = h + e1(e) + Ch(e,f,g) + 0x748f82ee + W[56]; - t2 = e0(a) + Maj(a,b,c); d+=t1; h=t1+t2; - t1 = g + e1(d) + Ch(d,e,f) + 0x78a5636f + W[57]; - t2 = e0(h) + Maj(h,a,b); c+=t1; g=t1+t2; - t1 = f + e1(c) + Ch(c,d,e) + 0x84c87814 + W[58]; - t2 = e0(g) + Maj(g,h,a); b+=t1; f=t1+t2; - t1 = e + e1(b) + Ch(b,c,d) + 0x8cc70208 + W[59]; - t2 = e0(f) + Maj(f,g,h); a+=t1; e=t1+t2; - t1 = d + e1(a) + Ch(a,b,c) + 0x90befffa + W[60]; - t2 = e0(e) + Maj(e,f,g); h+=t1; d=t1+t2; - t1 = c + e1(h) + Ch(h,a,b) + 0xa4506ceb + W[61]; - t2 = e0(d) + Maj(d,e,f); g+=t1; c=t1+t2; - t1 = b + e1(g) + Ch(g,h,a) + 0xbef9a3f7 + W[62]; - t2 = e0(c) + Maj(c,d,e); f+=t1; b=t1+t2; - t1 = a + e1(f) + Ch(f,g,h) + 0xc67178f2 + W[63]; - t2 = e0(b) + Maj(b,c,d); e+=t1; a=t1+t2; - - state[0] += a; state[1] += b; state[2] += c; state[3] += d; - state[4] += e; state[5] += f; state[6] += g; state[7] += h; - - /* clear any sensitive info... */ - a = b = c = d = e = f = g = h = t1 = t2 = 0; - memset(W, 0, 64 * sizeof(u32)); -} - /*}}}*/ -SHA256Summation::SHA256Summation() /*{{{*/ -{ - Sum.state[0] = H0; - Sum.state[1] = H1; - Sum.state[2] = H2; - Sum.state[3] = H3; - Sum.state[4] = H4; - Sum.state[5] = H5; - Sum.state[6] = H6; - Sum.state[7] = H7; - Sum.count[0] = Sum.count[1] = 0; - memset(Sum.buf, 0, sizeof(Sum.buf)); - Done = false; -} - /*}}}*/ -bool SHA256Summation::Add(const u8 *data, unsigned long len) /*{{{*/ -{ - struct sha256_ctx *sctx = ∑ - unsigned int i, index, part_len; - - if (Done) return false; - - /* Compute number of bytes mod 128 */ - index = (unsigned int)((sctx->count[0] >> 3) & 0x3f); - - /* Update number of bits */ - if ((sctx->count[0] += (len << 3)) < (len << 3)) { - sctx->count[1]++; - sctx->count[1] += (len >> 29); - } - - part_len = 64 - index; - - /* Transform as many times as possible. */ - if (len >= part_len) { - memcpy(&sctx->buf[index], data, part_len); - sha256_transform(sctx->state, sctx->buf); - - for (i = part_len; i + 63 < len; i += 64) - sha256_transform(sctx->state, &data[i]); - index = 0; - } else { - i = 0; - } - - /* Buffer remaining input */ - memcpy(&sctx->buf[index], &data[i], len-i); - - return true; -} - /*}}}*/ -SHA256SumValue SHA256Summation::Result() /*{{{*/ -{ - struct sha256_ctx *sctx = ∑ - if (!Done) { - u8 bits[8]; - unsigned int index, pad_len, t; - static const u8 padding[64] = { 0x80, }; - - /* Save number of bits */ - t = sctx->count[0]; - bits[7] = t; t >>= 8; - bits[6] = t; t >>= 8; - bits[5] = t; t >>= 8; - bits[4] = t; - t = sctx->count[1]; - bits[3] = t; t >>= 8; - bits[2] = t; t >>= 8; - bits[1] = t; t >>= 8; - bits[0] = t; - - /* Pad out to 56 mod 64. */ - index = (sctx->count[0] >> 3) & 0x3f; - pad_len = (index < 56) ? (56 - index) : ((64+56) - index); - Add(padding, pad_len); - - /* Append length (before padding) */ - Add(bits, 8); - } - - Done = true; - - /* Store state in digest */ - - SHA256SumValue res; - u8 *out = res.Sum; - - int i, j; - unsigned int t; - for (i = j = 0; i < 8; i++, j += 4) { - t = sctx->state[i]; - out[j+3] = t; t >>= 8; - out[j+2] = t; t >>= 8; - out[j+1] = t; t >>= 8; - out[j ] = t; - } - - return res; -} - /*}}}*/ -// SHA256SumValue::SHA256SumValue - Constructs the sum from a string /*{{{*/ -// --------------------------------------------------------------------- -/* The string form of a SHA256 is a 64 character hex number */ -SHA256SumValue::SHA256SumValue(string Str) -{ - memset(Sum,0,sizeof(Sum)); - Set(Str); -} - /*}}}*/ -// SHA256SumValue::SHA256SumValue - Default constructor /*{{{*/ -// --------------------------------------------------------------------- -/* Sets the value to 0 */ -SHA256SumValue::SHA256SumValue() -{ - memset(Sum,0,sizeof(Sum)); -} - /*}}}*/ -// SHA256SumValue::Set - Set the sum from a string /*{{{*/ -// --------------------------------------------------------------------- -/* Converts the hex string into a set of chars */ -bool SHA256SumValue::Set(string Str) -{ - return Hex2Num(Str,Sum,sizeof(Sum)); -} - /*}}}*/ -// SHA256SumValue::Value - Convert the number into a string /*{{{*/ -// --------------------------------------------------------------------- -/* Converts the set of chars into a hex string in lower case */ -string SHA256SumValue::Value() const -{ - char Conv[16] = - { '0','1','2','3','4','5','6','7','8','9','a','b', - 'c','d','e','f' - }; - char Result[65]; - Result[64] = 0; - - // Convert each char into two letters - int J = 0; - int I = 0; - for (; I != 64; J++,I += 2) - { - Result[I] = Conv[Sum[J] >> 4]; - Result[I + 1] = Conv[Sum[J] & 0xF]; - } - - return string(Result); -} - /*}}}*/ -// SHA256SumValue::operator == - Comparator /*{{{*/ -// --------------------------------------------------------------------- -/* Call memcmp on the buffer */ -bool SHA256SumValue::operator == (const SHA256SumValue & rhs) const -{ - return memcmp(Sum,rhs.Sum,sizeof(Sum)) == 0; -} - /*}}}*/ -// SHA256Summation::AddFD - Add content of file into the checksum /*{{{*/ -// --------------------------------------------------------------------- -/* */ -bool SHA256Summation::AddFD(int Fd,unsigned long Size) -{ - unsigned char Buf[64 * 64]; - int Res = 0; - int ToEOF = (Size == 0); - while (Size != 0 || ToEOF) - { - unsigned n = sizeof(Buf); - if (!ToEOF) n = min(Size,(unsigned long)n); - Res = read(Fd,Buf,n); - if (Res < 0 || (!ToEOF && (unsigned) Res != n)) // error, or short read - return false; - if (ToEOF && Res == 0) // EOF - break; - Size -= Res; - Add(Buf,Res); - } - return true; -} - /*}}}*/ - diff --git a/apt-pkg/contrib/sha256.h b/apt-pkg/contrib/sha256.h index 5934b5641..15146c948 100644 --- a/apt-pkg/contrib/sha256.h +++ b/apt-pkg/contrib/sha256.h @@ -1,72 +1,8 @@ -// -*- mode: cpp; mode: fold -*- -// Description /*{{{*/ -// $Id: sha1.h,v 1.3 2001/05/07 05:05:47 jgg Exp $ -/* ###################################################################### - - SHA256SumValue - Storage for a SHA-256 hash. - SHA256Summation - SHA-256 Secure Hash Algorithm. - - This is a C++ interface to a set of SHA256Sum functions, that mirrors - the equivalent MD5 & SHA1 classes. - - ##################################################################### */ - /*}}}*/ #ifndef APTPKG_SHA256_H #define APTPKG_SHA256_H -#include <string> -#include <cstring> -#include <algorithm> -#include <stdint.h> - -using std::string; -using std::min; - -class SHA256Summation; - -class SHA256SumValue -{ - friend class SHA256Summation; - unsigned char Sum[32]; - - public: - - // Accessors - bool operator ==(const SHA256SumValue &rhs) const; - string Value() const; - inline void Value(unsigned char S[32]) - {for (int I = 0; I != sizeof(Sum); I++) S[I] = Sum[I];}; - inline operator string() const {return Value();}; - bool Set(string Str); - inline void Set(unsigned char S[32]) - {for (int I = 0; I != sizeof(Sum); I++) Sum[I] = S[I];}; - - SHA256SumValue(string Str); - SHA256SumValue(); -}; - -struct sha256_ctx { - uint32_t count[2]; - uint32_t state[8]; - uint8_t buf[128]; -}; - -class SHA256Summation -{ - struct sha256_ctx Sum; - - bool Done; - - public: +#include "sha2.h" - bool Add(const unsigned char *inbuf,unsigned long inlen); - inline bool Add(const char *Data) {return Add((unsigned char *)Data,strlen(Data));}; - bool AddFD(int Fd,unsigned long Size); - inline bool Add(const unsigned char *Beg,const unsigned char *End) - {return Add(Beg,End-Beg);}; - SHA256SumValue Result(); - - SHA256Summation(); -}; +#warning "This header is deprecated, please include sha2.h instead" #endif diff --git a/apt-pkg/contrib/sha2_internal.cc b/apt-pkg/contrib/sha2_internal.cc new file mode 100644 index 000000000..565db2f91 --- /dev/null +++ b/apt-pkg/contrib/sha2_internal.cc @@ -0,0 +1,1065 @@ +/* + * FILE: sha2.c + * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ + * + * Copyright (c) 2000-2001, Aaron D. Gifford + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $ + */ + +#include <string.h> /* memcpy()/memset() or bcopy()/bzero() */ +#include <assert.h> /* assert() */ +#include "sha2_internal.h" + +/* + * ASSERT NOTE: + * Some sanity checking code is included using assert(). On my FreeBSD + * system, this additional code can be removed by compiling with NDEBUG + * defined. Check your own systems manpage on assert() to see how to + * compile WITHOUT the sanity checking code on your system. + * + * UNROLLED TRANSFORM LOOP NOTE: + * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform + * loop version for the hash transform rounds (defined using macros + * later in this file). Either define on the command line, for example: + * + * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c + * + * or define below: + * + * #define SHA2_UNROLL_TRANSFORM + * + */ + + +/*** SHA-256/384/512 Machine Architecture Definitions *****************/ +/* + * BYTE_ORDER NOTE: + * + * 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. + * + * If your system does not define the above, then you can do so by + * hand like this: + * + * #define LITTLE_ENDIAN 1234 + * #define BIG_ENDIAN 4321 + * + * And for little-endian machines, add: + * + * #define BYTE_ORDER LITTLE_ENDIAN + * + * Or for big-endian machines: + * + * #define BYTE_ORDER BIG_ENDIAN + * + * The FreeBSD machine this was written on defines BYTE_ORDER + * appropriately by including <sys/types.h> (which in turn includes + * <machine/endian.h> where the appropriate definitions are actually + * made). + */ +#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) +#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN +#endif + +/* + * Define the followingsha2_* types to types of the correct length on + * the native archtecture. Most BSD systems and Linux define u_intXX_t + * types. Machines with very recent ANSI C headers, can use the + * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H + * during compile or in the sha.h header file. + * + * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t + * will need to define these three typedefs below (and the appropriate + * ones in sha.h too) by hand according to their system architecture. + * + * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t + * types and pointing out recent ANSI C support for uintXX_t in inttypes.h. + */ +#ifdef SHA2_USE_INTTYPES_H + +typedef uint8_t sha2_byte; /* Exactly 1 byte */ +typedef uint32_t sha2_word32; /* Exactly 4 bytes */ +typedef uint64_t sha2_word64; /* Exactly 8 bytes */ + +#else /* SHA2_USE_INTTYPES_H */ + +typedef u_int8_t sha2_byte; /* Exactly 1 byte */ +typedef u_int32_t sha2_word32; /* Exactly 4 bytes */ +typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ + +#endif /* SHA2_USE_INTTYPES_H */ + + +/*** SHA-256/384/512 Various Length Definitions ***********************/ +/* NOTE: Most of these are in sha2.h */ +#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) +#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16) +#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) + + +/*** ENDIAN REVERSAL MACROS *******************************************/ +#if BYTE_ORDER == LITTLE_ENDIAN +#define REVERSE32(w,x) { \ + sha2_word32 tmp = (w); \ + tmp = (tmp >> 16) | (tmp << 16); \ + (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ +} +#define REVERSE64(w,x) { \ + sha2_word64 tmp = (w); \ + tmp = (tmp >> 32) | (tmp << 32); \ + tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ + ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ + (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ + ((tmp & 0x0000ffff0000ffffULL) << 16); \ +} +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +/* + * Macro for incrementally adding the unsigned 64-bit integer n to the + * unsigned 128-bit integer (represented using a two-element array of + * 64-bit words): + */ +#define ADDINC128(w,n) { \ + (w)[0] += (sha2_word64)(n); \ + if ((w)[0] < (n)) { \ + (w)[1]++; \ + } \ +} + +/* + * Macros for copying blocks of memory and for zeroing out ranges + * of memory. Using these macros makes it easy to switch from + * using memset()/memcpy() and using bzero()/bcopy(). + * + * Please define either SHA2_USE_MEMSET_MEMCPY or define + * SHA2_USE_BZERO_BCOPY depending on which function set you + * choose to use: + */ +#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY) +/* Default to memset()/memcpy() if no option is specified */ +#define SHA2_USE_MEMSET_MEMCPY 1 +#endif +#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY) +/* Abort with an error if BOTH options are defined */ +#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both! +#endif + +#ifdef SHA2_USE_MEMSET_MEMCPY +#define MEMSET_BZERO(p,l) memset((p), 0, (l)) +#define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l)) +#endif +#ifdef SHA2_USE_BZERO_BCOPY +#define MEMSET_BZERO(p,l) bzero((p), (l)) +#define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l)) +#endif + + +/*** THE SIX LOGICAL FUNCTIONS ****************************************/ +/* + * Bit shifting and rotation (used by the six SHA-XYZ logical functions: + * + * NOTE: The naming of R and S appears backwards here (R is a SHIFT and + * S is a ROTATION) because the SHA-256/384/512 description document + * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this + * same "backwards" definition. + */ +/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ +#define R(b,x) ((x) >> (b)) +/* 32-bit Rotate-right (used in SHA-256): */ +#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) +/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ +#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) + +/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ +#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +/* Four of six logical functions used in SHA-256: */ +#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) +#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) +#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) +#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) + +/* Four of six logical functions used in SHA-384 and SHA-512: */ +#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) +#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) +#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) +#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) + +/*** INTERNAL FUNCTION PROTOTYPES *************************************/ +/* NOTE: These should not be accessed directly from outside this + * library -- they are intended for private internal visibility/use + * only. + */ +static void SHA512_Last(SHA512_CTX*); +static void SHA256_Transform(SHA256_CTX*, const sha2_word32*); +static void SHA512_Transform(SHA512_CTX*, const sha2_word64*); + + +/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ +/* Hash constant words K for SHA-256: */ +const static sha2_word32 K256[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + +/* Initial hash value H for SHA-256: */ +const static sha2_word32 sha256_initial_hash_value[8] = { + 0x6a09e667UL, + 0xbb67ae85UL, + 0x3c6ef372UL, + 0xa54ff53aUL, + 0x510e527fUL, + 0x9b05688cUL, + 0x1f83d9abUL, + 0x5be0cd19UL +}; + +/* Hash constant words K for SHA-384 and SHA-512: */ +const static sha2_word64 K512[80] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, + 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, + 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, + 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, + 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, + 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, + 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, + 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, + 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, + 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, + 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, + 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, + 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, + 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, + 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, + 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, + 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, + 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, + 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, + 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, + 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, + 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, + 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, + 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, + 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, + 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, + 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, + 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, + 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, + 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, + 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, + 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, + 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, + 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL +}; + +/* Initial hash value H for SHA-384 */ +const static sha2_word64 sha384_initial_hash_value[8] = { + 0xcbbb9d5dc1059ed8ULL, + 0x629a292a367cd507ULL, + 0x9159015a3070dd17ULL, + 0x152fecd8f70e5939ULL, + 0x67332667ffc00b31ULL, + 0x8eb44a8768581511ULL, + 0xdb0c2e0d64f98fa7ULL, + 0x47b5481dbefa4fa4ULL +}; + +/* Initial hash value H for SHA-512 */ +const static sha2_word64 sha512_initial_hash_value[8] = { + 0x6a09e667f3bcc908ULL, + 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, + 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, + 0x5be0cd19137e2179ULL +}; + +/* + * Constant used by SHA256/384/512_End() functions for converting the + * digest to a readable hexadecimal character string: + */ +static const char *sha2_hex_digits = "0123456789abcdef"; + + +/*** SHA-256: *********************************************************/ +void SHA256_Init(SHA256_CTX* context) { + if (context == (SHA256_CTX*)0) { + return; + } + MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH); + context->bitcount = 0; +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-256 round macros: */ + +#if BYTE_ORDER == LITTLE_ENDIAN + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + REVERSE32(*data++, W256[j]); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + W256[j]; \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + + +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + (W256[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND256(a,b,c,d,e,f,g,h) \ + s0 = W256[(j+1)&0x0f]; \ + s0 = sigma0_256(s0); \ + s1 = W256[(j+14)&0x0f]; \ + s1 = sigma1_256(s1); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + +static void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1, *W256; + int j; + + W256 = (sha2_word32*)context->buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { + /* Rounds 0 to 15 (unrolled): */ + ROUND256_0_TO_15(a,b,c,d,e,f,g,h); + ROUND256_0_TO_15(h,a,b,c,d,e,f,g); + ROUND256_0_TO_15(g,h,a,b,c,d,e,f); + ROUND256_0_TO_15(f,g,h,a,b,c,d,e); + ROUND256_0_TO_15(e,f,g,h,a,b,c,d); + ROUND256_0_TO_15(d,e,f,g,h,a,b,c); + ROUND256_0_TO_15(c,d,e,f,g,h,a,b); + ROUND256_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds to 64: */ + do { + ROUND256(a,b,c,d,e,f,g,h); + ROUND256(h,a,b,c,d,e,f,g); + ROUND256(g,h,a,b,c,d,e,f); + ROUND256(f,g,h,a,b,c,d,e); + ROUND256(e,f,g,h,a,b,c,d); + ROUND256(d,e,f,g,h,a,b,c); + ROUND256(c,d,e,f,g,h,a,b); + ROUND256(b,c,d,e,f,g,h,a); + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +static void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1, T2, *W256; + int j; + + W256 = (sha2_word32*)context->buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { +#if BYTE_ORDER == LITTLE_ENDIAN + /* Copy data while converting to host byte order */ + REVERSE32(*data++,W256[j]); + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + /* Apply the SHA-256 compression function to update a..h with copy */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W256[(j+1)&0x0f]; + s0 = sigma0_256(s0); + s1 = W256[(j+14)&0x0f]; + s1 = sigma1_256(s1); + + /* Apply the SHA-256 compression function to update a..h */ + T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); + T2 = Sigma0_256(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); + + usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA256_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); + context->bitcount += freespace << 3; + len -= freespace; + data += freespace; + SHA256_Transform(context, (sha2_word32*)context->buffer); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, len); + context->bitcount += len << 3; + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA256_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + SHA256_Transform(context, (sha2_word32*)data); + context->bitcount += SHA256_BLOCK_LENGTH << 3; + len -= SHA256_BLOCK_LENGTH; + data += SHA256_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->buffer, data, len); + context->bitcount += len << 3; + } + /* Clean up: */ + usedspace = freespace = 0; +} + +void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) { + sha2_word32 *d = (sha2_word32*)digest; + unsigned int usedspace; + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->bitcount,context->bitcount); +#endif + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA256_BLOCK_LENGTH) { + MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA256_Transform(context, (sha2_word32*)context->buffer); + + /* And set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); + } + } else { + /* Set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Set the bit count: */ + *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount; + + /* Final transform: */ + SHA256_Transform(context, (sha2_word32*)context->buffer); + +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 8; j++) { + REVERSE32(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH); +#endif + } + + /* Clean up state data: */ + MEMSET_BZERO(context, sizeof(context)); + usedspace = 0; +} + +char *SHA256_End(SHA256_CTX* context, char buffer[]) { + sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA256_CTX*)0); + + if (buffer != (char*)0) { + SHA256_Final(digest, context); + + for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(context)); + } + MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH); + return buffer; +} + +char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { + SHA256_CTX context; + + SHA256_Init(&context); + SHA256_Update(&context, data, len); + return SHA256_End(&context, digest); +} + + +/*** SHA-512: *********************************************************/ +void SHA512_Init(SHA512_CTX* context) { + if (context == (SHA512_CTX*)0) { + return; + } + MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; +} + +#ifdef SHA2_UNROLL_TRANSFORM + +/* Unrolled SHA-512 round macros: */ +#if BYTE_ORDER == LITTLE_ENDIAN + +#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ + REVERSE64(*data++, W512[j]); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + K512[j] + W512[j]; \ + (d) += T1, \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ + j++ + + +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + K512[j] + (W512[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ + +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +#define ROUND512(a,b,c,d,e,f,g,h) \ + s0 = W512[(j+1)&0x0f]; \ + s0 = sigma0_512(s0); \ + s1 = W512[(j+14)&0x0f]; \ + s1 = sigma1_512(s1); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ + +static void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { + sha2_word64 a, b, c, d, e, f, g, h, s0, s1; + sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { + ROUND512_0_TO_15(a,b,c,d,e,f,g,h); + ROUND512_0_TO_15(h,a,b,c,d,e,f,g); + ROUND512_0_TO_15(g,h,a,b,c,d,e,f); + ROUND512_0_TO_15(f,g,h,a,b,c,d,e); + ROUND512_0_TO_15(e,f,g,h,a,b,c,d); + ROUND512_0_TO_15(d,e,f,g,h,a,b,c); + ROUND512_0_TO_15(c,d,e,f,g,h,a,b); + ROUND512_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds up to 79: */ + do { + ROUND512(a,b,c,d,e,f,g,h); + ROUND512(h,a,b,c,d,e,f,g); + ROUND512(g,h,a,b,c,d,e,f); + ROUND512(f,g,h,a,b,c,d,e); + ROUND512(e,f,g,h,a,b,c,d); + ROUND512(d,e,f,g,h,a,b,c); + ROUND512(c,d,e,f,g,h,a,b); + ROUND512(b,c,d,e,f,g,h,a); + } while (j < 80); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; +} + +#else /* SHA2_UNROLL_TRANSFORM */ + +static void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { + sha2_word64 a, b, c, d, e, f, g, h, s0, s1; + sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; + int j; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert TO host byte order */ + REVERSE64(*data++, W512[j]); + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + /* Apply the SHA-512 compression function to update a..h with copy */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 16); + + do { + /* Part of the message block expansion: */ + s0 = W512[(j+1)&0x0f]; + s0 = sigma0_512(s0); + s1 = W512[(j+14)&0x0f]; + s1 = sigma1_512(s1); + + /* Apply the SHA-512 compression function to update a..h */ + T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); + T2 = Sigma0_512(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + + j++; + } while (j < 80); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = T2 = 0; +} + +#endif /* SHA2_UNROLL_TRANSFORM */ + +void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); + + usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA512_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); + ADDINC128(context->bitcount, freespace << 3); + len -= freespace; + data += freespace; + SHA512_Transform(context, (sha2_word64*)context->buffer); + } else { + /* The buffer is not yet full */ + MEMCPY_BCOPY(&context->buffer[usedspace], data, len); + ADDINC128(context->bitcount, len << 3); + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA512_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + SHA512_Transform(context, (sha2_word64*)data); + ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); + len -= SHA512_BLOCK_LENGTH; + data += SHA512_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + MEMCPY_BCOPY(context->buffer, data, len); + ADDINC128(context->bitcount, len << 3); + } + /* Clean up: */ + usedspace = freespace = 0; +} + +static void SHA512_Last(SHA512_CTX* context) { + unsigned int usedspace; + + usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; +#if BYTE_ORDER == LITTLE_ENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->bitcount[0],context->bitcount[0]); + REVERSE64(context->bitcount[1],context->bitcount[1]); +#endif + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA512_BLOCK_LENGTH) { + MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA512_Transform(context, (sha2_word64*)context->buffer); + + /* And set-up for the last transform: */ + MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2); + } + } else { + /* Prepare for final transform: */ + MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Store the length of input data (in bits): */ + *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1]; + *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0]; + + /* Final transform: */ + SHA512_Transform(context, (sha2_word64*)context->buffer); +} + +void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) { + sha2_word64 *d = (sha2_word64*)digest; + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + SHA512_Last(context); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 8; j++) { + REVERSE64(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH); +#endif + } + + /* Zero out state data */ + MEMSET_BZERO(context, sizeof(context)); +} + +char *SHA512_End(SHA512_CTX* context, char buffer[]) { + sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA512_CTX*)0); + + if (buffer != (char*)0) { + SHA512_Final(digest, context); + + for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(context)); + } + MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH); + return buffer; +} + +char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { + SHA512_CTX context; + + SHA512_Init(&context); + SHA512_Update(&context, data, len); + return SHA512_End(&context, digest); +} + + +/*** SHA-384: *********************************************************/ +void SHA384_Init(SHA384_CTX* context) { + if (context == (SHA384_CTX*)0) { + return; + } + MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH); + MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH); + context->bitcount[0] = context->bitcount[1] = 0; +} + +void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { + SHA512_Update((SHA512_CTX*)context, data, len); +} + +void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) { + sha2_word64 *d = (sha2_word64*)digest; + + /* Sanity check: */ + assert(context != (SHA384_CTX*)0); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + SHA512_Last((SHA512_CTX*)context); + + /* Save the hash data for output: */ +#if BYTE_ORDER == LITTLE_ENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 6; j++) { + REVERSE64(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH); +#endif + } + + /* Zero out state data */ + MEMSET_BZERO(context, sizeof(context)); +} + +char *SHA384_End(SHA384_CTX* context, char buffer[]) { + sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; + int i; + + /* Sanity check: */ + assert(context != (SHA384_CTX*)0); + + if (buffer != (char*)0) { + SHA384_Final(digest, context); + + for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char)0; + } else { + MEMSET_BZERO(context, sizeof(context)); + } + MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH); + return buffer; +} + +char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { + SHA384_CTX context; + + SHA384_Init(&context); + SHA384_Update(&context, data, len); + return SHA384_End(&context, digest); +} + diff --git a/apt-pkg/contrib/sha2_internal.h b/apt-pkg/contrib/sha2_internal.h new file mode 100644 index 000000000..d9d429c92 --- /dev/null +++ b/apt-pkg/contrib/sha2_internal.h @@ -0,0 +1,188 @@ +/* + * FILE: sha2.h + * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ + * + * Copyright (c) 2000-2001, Aaron D. Gifford + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $ + */ + +#ifndef __SHA2_H__ +#define __SHA2_H__ + +/* + * Import u_intXX_t size_t type definitions from system headers. You + * may need to change this, or define these things yourself in this + * file. + */ +#include <sys/types.h> + +#ifdef SHA2_USE_INTTYPES_H + +#include <inttypes.h> + +#endif /* SHA2_USE_INTTYPES_H */ + + +/*** SHA-256/384/512 Various Length Definitions ***********************/ +#define SHA256_BLOCK_LENGTH 64 +#define SHA256_DIGEST_LENGTH 32 +#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) +#define SHA384_BLOCK_LENGTH 128 +#define SHA384_DIGEST_LENGTH 48 +#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) +#define SHA512_BLOCK_LENGTH 128 +#define SHA512_DIGEST_LENGTH 64 +#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) + + +/*** SHA-256/384/512 Context Structures *******************************/ +/* NOTE: If your architecture does not define either u_intXX_t types or + * uintXX_t (from inttypes.h), you may need to define things by hand + * for your system: + */ +#if 0 +typedef unsigned char u_int8_t; /* 1-byte (8-bits) */ +typedef unsigned int u_int32_t; /* 4-bytes (32-bits) */ +typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */ +#endif +/* + * Most BSD systems already define u_intXX_t types, as does Linux. + * Some systems, however, like Compaq's Tru64 Unix instead can use + * uintXX_t types defined by very recent ANSI C standards and included + * in the file: + * + * #include <inttypes.h> + * + * If you choose to use <inttypes.h> then please define: + * + * #define SHA2_USE_INTTYPES_H + * + * Or on the command line during compile: + * + * cc -DSHA2_USE_INTTYPES_H ... + */ +#ifdef SHA2_USE_INTTYPES_H + +typedef struct _SHA256_CTX { + uint32_t state[8]; + uint64_t bitcount; + uint8_t buffer[SHA256_BLOCK_LENGTH]; +} SHA256_CTX; +typedef struct _SHA512_CTX { + uint64_t state[8]; + uint64_t bitcount[2]; + uint8_t buffer[SHA512_BLOCK_LENGTH]; +} SHA512_CTX; + +#else /* SHA2_USE_INTTYPES_H */ + +typedef struct _SHA256_CTX { + u_int32_t state[8]; + u_int64_t bitcount; + u_int8_t buffer[SHA256_BLOCK_LENGTH]; +} SHA256_CTX; +typedef struct _SHA512_CTX { + u_int64_t state[8]; + u_int64_t bitcount[2]; + u_int8_t buffer[SHA512_BLOCK_LENGTH]; +} SHA512_CTX; + +#endif /* SHA2_USE_INTTYPES_H */ + +typedef SHA512_CTX SHA384_CTX; + + +/*** SHA-256/384/512 Function Prototypes ******************************/ +#ifndef NOPROTO +#ifdef SHA2_USE_INTTYPES_H + +void SHA256_Init(SHA256_CTX *); +void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t); +void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); +char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); +char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); + +void SHA384_Init(SHA384_CTX*); +void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t); +void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); +char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); +char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); + +void SHA512_Init(SHA512_CTX*); +void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t); +void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); +char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); +char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); + +#else /* SHA2_USE_INTTYPES_H */ + +void SHA256_Init(SHA256_CTX *); +void SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t); +void SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); +char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); +char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); + +void SHA384_Init(SHA384_CTX*); +void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t); +void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); +char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); +char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); + +void SHA512_Init(SHA512_CTX*); +void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t); +void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); +char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); +char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); + +#endif /* SHA2_USE_INTTYPES_H */ + +#else /* NOPROTO */ + +void SHA256_Init(); +void SHA256_Update(); +void SHA256_Final(); +char* SHA256_End(); +char* SHA256_Data(); + +void SHA384_Init(); +void SHA384_Update(); +void SHA384_Final(); +char* SHA384_End(); +char* SHA384_Data(); + +void SHA512_Init(); +void SHA512_Update(); +void SHA512_Final(); +char* SHA512_End(); +char* SHA512_Data(); + +#endif /* NOPROTO */ + +#endif /* __SHA2_H__ */ + diff --git a/apt-pkg/deb/debindexfile.h b/apt-pkg/deb/debindexfile.h index b5085992d..678c22473 100644 --- a/apt-pkg/deb/debindexfile.h +++ b/apt-pkg/deb/debindexfile.h @@ -22,8 +22,12 @@ class debStatusIndex : public pkgIndexFile { + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; + + protected: string File; - + public: virtual const Type *GetType() const; @@ -36,13 +40,18 @@ class debStatusIndex : public pkgIndexFile virtual bool HasPackages() const {return true;}; virtual unsigned long Size() const; virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const; + bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog, unsigned long const Flag) const; virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; debStatusIndex(string File); + virtual ~debStatusIndex() {}; }; class debPackagesIndex : public pkgIndexFile { + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; + string URI; string Dist; string Section; @@ -72,10 +81,14 @@ class debPackagesIndex : public pkgIndexFile debPackagesIndex(string const &URI, string const &Dist, string const &Section, bool const &Trusted, string const &Arch = "native"); + virtual ~debPackagesIndex() {}; }; class debTranslationsIndex : public pkgIndexFile { + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; + string URI; string Dist; string Section; @@ -103,10 +116,14 @@ class debTranslationsIndex : public pkgIndexFile virtual pkgCache::PkgFileIterator FindInCache(pkgCache &Cache) const; debTranslationsIndex(string URI,string Dist,string Section, char const * const Language); + virtual ~debTranslationsIndex() {}; }; class debSourcesIndex : public pkgIndexFile { + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; + string URI; string Dist; string Section; @@ -136,6 +153,7 @@ class debSourcesIndex : public pkgIndexFile virtual unsigned long Size() const; debSourcesIndex(string URI,string Dist,string Section,bool Trusted); + virtual ~debSourcesIndex() {}; }; #endif diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 8d3f6f0ba..952433428 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -128,12 +128,7 @@ bool debListParser::NewVersion(pkgCache::VerIterator &Ver) } if (ArchitectureAll() == true) - switch (Ver->MultiArch) - { - case pkgCache::Version::Foreign: Ver->MultiArch = pkgCache::Version::AllForeign; break; - case pkgCache::Version::Allowed: Ver->MultiArch = pkgCache::Version::AllAllowed; break; - default: Ver->MultiArch = pkgCache::Version::All; - } + Ver->MultiArch |= pkgCache::Version::All; // Archive Size Ver->Size = Section.FindULL("Size"); @@ -690,12 +685,12 @@ bool debListParser::ParseProvides(pkgCache::VerIterator &Ver) if (MultiArchEnabled == false) return true; - else if (Ver->MultiArch == pkgCache::Version::Allowed || Ver->MultiArch == pkgCache::Version::AllAllowed) + else 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()); } - else if (Ver->MultiArch == pkgCache::Version::Foreign || Ver->MultiArch == pkgCache::Version::AllForeign) + else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign) return NewProvidesAllArch(Ver, Ver.ParentPkg().Name(), Ver.VerStr()); return true; diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h index d62ce641c..41d712fbf 100644 --- a/apt-pkg/deb/deblistparser.h +++ b/apt-pkg/deb/deblistparser.h @@ -25,9 +25,12 @@ class debListParser : public pkgCacheGenerator::ListParser const char *Str; unsigned char Val; }; - + private: - + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; + + protected: pkgTagFile Tags; pkgTagSection Section; unsigned long iOffset; @@ -36,7 +39,7 @@ class debListParser : public pkgCacheGenerator::ListParser bool MultiArchEnabled; unsigned long UniqFindTagWrite(const char *Tag); - bool ParseStatus(pkgCache::PkgIterator &Pkg,pkgCache::VerIterator &Ver); + virtual bool ParseStatus(pkgCache::PkgIterator &Pkg,pkgCache::VerIterator &Ver); bool ParseDepends(pkgCache::VerIterator &Ver,const char *Tag, unsigned int Type); bool ParseProvides(pkgCache::VerIterator &Ver); @@ -74,6 +77,7 @@ class debListParser : public pkgCacheGenerator::ListParser static const char *ConvertRelation(const char *I,unsigned int &Op); debListParser(FileFd *File, string const &Arch = ""); + virtual ~debListParser() {}; }; #endif diff --git a/apt-pkg/deb/debmetaindex.cc b/apt-pkg/deb/debmetaindex.cc index f6c50742e..e1f8219e3 100644 --- a/apt-pkg/deb/debmetaindex.cc +++ b/apt-pkg/deb/debmetaindex.cc @@ -142,11 +142,13 @@ string debReleaseIndex::TranslationIndexURI(const char *Type, const string &Sect return URI + "dists/" + Dist + "/" + TranslationIndexURISuffix(Type, Section); } -debReleaseIndex::debReleaseIndex(string const &URI, string const &Dist) { - this->URI = URI; - this->Dist = Dist; - this->Indexes = NULL; - this->Type = "deb"; +debReleaseIndex::debReleaseIndex(string const &URI, string const &Dist) : + metaIndex(URI, Dist, "deb"), Trusted(CHECK_TRUST) +{} + +debReleaseIndex::debReleaseIndex(string const &URI, string const &Dist, bool const Trusted) : + metaIndex(URI, Dist, "deb") { + SetTrusted(Trusted); } debReleaseIndex::~debReleaseIndex() { @@ -252,8 +254,22 @@ bool debReleaseIndex::GetIndexes(pkgAcquire *Owner, bool const &GetAll) const return true; } +void debReleaseIndex::SetTrusted(bool const Trusted) +{ + if (Trusted == true) + this->Trusted = ALWAYS_TRUSTED; + else + this->Trusted = NEVER_TRUSTED; +} + bool debReleaseIndex::IsTrusted() const { + if (Trusted == ALWAYS_TRUSTED) + return true; + else if (Trusted == NEVER_TRUSTED) + return false; + + if(_config->FindB("APT::Authentication::TrustCDROM", false)) if(URI.substr(0,strlen("cdrom:")) == "cdrom:") return true; @@ -349,6 +365,7 @@ class debSLTypeDebian : public pkgSourceList::Type vector<string> const Archs = (arch != Options.end()) ? VectorizeString(arch->second, ',') : APT::Configuration::getArchitectures(); + map<string, string>::const_iterator const trusted = Options.find("trusted"); for (vector<metaIndex *>::const_iterator I = List.begin(); I != List.end(); ++I) @@ -358,6 +375,9 @@ class debSLTypeDebian : public pkgSourceList::Type continue; debReleaseIndex *Deb = (debReleaseIndex *) (*I); + if (trusted != Options.end()) + Deb->SetTrusted(StringToBool(trusted->second, false)); + /* This check insures that there will be only one Release file queued for all the Packages files and Sources files it corresponds to. */ @@ -375,9 +395,14 @@ class debSLTypeDebian : public pkgSourceList::Type return true; } } + // No currently created Release file indexes this entry, so we create a new one. - // XXX determine whether this release is trusted or not - debReleaseIndex *Deb = new debReleaseIndex(URI, Dist); + debReleaseIndex *Deb; + if (trusted != Options.end()) + Deb = new debReleaseIndex(URI, Dist, StringToBool(trusted->second, false)); + else + Deb = new debReleaseIndex(URI, Dist); + if (IsSrc == true) Deb->PushSectionEntry ("source", new debReleaseIndex::debSectionEntry(Section, IsSrc)); else diff --git a/apt-pkg/deb/debmetaindex.h b/apt-pkg/deb/debmetaindex.h index 1561c6e00..695cfa7cc 100644 --- a/apt-pkg/deb/debmetaindex.h +++ b/apt-pkg/deb/debmetaindex.h @@ -19,12 +19,16 @@ class debReleaseIndex : public metaIndex { }; private: + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; std::map<string, vector<debSectionEntry const*> > ArchEntries; + enum { ALWAYS_TRUSTED, NEVER_TRUSTED, CHECK_TRUST } Trusted; public: debReleaseIndex(string const &URI, string const &Dist); - ~debReleaseIndex(); + debReleaseIndex(string const &URI, string const &Dist, bool const Trusted); + virtual ~debReleaseIndex(); virtual string ArchiveURI(string const &File) const {return URI + File;}; virtual bool GetIndexes(pkgAcquire *Owner, bool const &GetAll=false) const; @@ -41,6 +45,7 @@ class debReleaseIndex : public metaIndex { string TranslationIndexURISuffix(const char *Type, const string &Section) const; virtual vector <pkgIndexFile *> *GetIndexFiles(); + void SetTrusted(bool const Trusted); virtual bool IsTrusted() const; void PushSectionEntry(vector<string> const &Archs, const debSectionEntry *Entry); diff --git a/apt-pkg/deb/debrecords.cc b/apt-pkg/deb/debrecords.cc index 7f596ab0d..2571aae52 100644 --- a/apt-pkg/deb/debrecords.cc +++ b/apt-pkg/deb/debrecords.cc @@ -77,7 +77,7 @@ string debRecordParser::SHA1Hash() return Section.FindS("SHA1"); } /*}}}*/ -// RecordParser::SHA1Hash - Return the archive hash /*{{{*/ +// RecordParser::SHA256Hash - Return the archive hash /*{{{*/ // --------------------------------------------------------------------- /* */ string debRecordParser::SHA256Hash() @@ -85,6 +85,14 @@ string debRecordParser::SHA256Hash() return Section.FindS("SHA256"); } /*}}}*/ +// RecordParser::SHA512Hash - Return the archive hash /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::SHA512Hash() +{ + return Section.FindS("SHA512"); +} + /*}}}*/ // RecordParser::Maintainer - Return the maintainer email /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -93,6 +101,15 @@ string debRecordParser::Maintainer() return Section.FindS("Maintainer"); } /*}}}*/ +// RecordParser::RecordField - Return the value of an arbitrary field /*{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::RecordField(const char *fieldName) +{ + return Section.FindS(fieldName); +} + + /*}}}*/ // RecordParser::ShortDesc - Return a 1 line description /*{{{*/ // --------------------------------------------------------------------- /* */ diff --git a/apt-pkg/deb/debrecords.h b/apt-pkg/deb/debrecords.h index 6f358abfa..7868bfa3d 100644 --- a/apt-pkg/deb/debrecords.h +++ b/apt-pkg/deb/debrecords.h @@ -20,6 +20,9 @@ class debRecordParser : public pkgRecords::Parser { + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; + FileFd File; pkgTagFile Tags; pkgTagSection Section; @@ -36,6 +39,7 @@ class debRecordParser : public pkgRecords::Parser virtual string MD5Hash(); virtual string SHA1Hash(); virtual string SHA256Hash(); + virtual string SHA512Hash(); virtual string SourcePkg(); virtual string SourceVer(); @@ -46,9 +50,13 @@ class debRecordParser : public pkgRecords::Parser virtual string Name(); virtual string Homepage(); + // An arbitrary custom field + virtual string RecordField(const char *fieldName); + virtual void GetRec(const char *&Start,const char *&Stop); debRecordParser(string FileName,pkgCache &Cache); + virtual ~debRecordParser() {}; }; #endif diff --git a/apt-pkg/deb/debsrcrecords.h b/apt-pkg/deb/debsrcrecords.h index 905264daa..aa859b0e6 100644 --- a/apt-pkg/deb/debsrcrecords.h +++ b/apt-pkg/deb/debsrcrecords.h @@ -18,6 +18,9 @@ class debSrcRecordParser : public pkgSrcRecords::Parser { + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; + FileFd Fd; pkgTagFile Tags; pkgTagSection Sect; @@ -50,7 +53,7 @@ class debSrcRecordParser : public pkgSrcRecords::Parser debSrcRecordParser(string const &File,pkgIndexFile const *Index) : Parser(Index), Fd(File,FileFd::ReadOnlyGzip), Tags(&Fd,102400), Buffer(0), BufSize(0) {} - ~debSrcRecordParser(); + virtual ~debSrcRecordParser(); }; #endif diff --git a/apt-pkg/deb/debsystem.cc b/apt-pkg/deb/debsystem.cc index 8619822df..7644bc66b 100644 --- a/apt-pkg/deb/debsystem.cc +++ b/apt-pkg/deb/debsystem.cc @@ -26,15 +26,24 @@ debSystem debSys; +class debSystemPrivate { +public: + debSystemPrivate() : LockFD(-1), LockCount(0), StatusFile(0) + { + } + // For locking support + int LockFD; + unsigned LockCount; + + debStatusIndex *StatusFile; +}; + // System::debSystem - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ debSystem::debSystem() { - LockFD = -1; - LockCount = 0; - StatusFile = 0; - + d = new debSystemPrivate(); Label = "Debian dpkg interface"; VS = &debVS; } @@ -44,7 +53,8 @@ debSystem::debSystem() /* */ debSystem::~debSystem() { - delete StatusFile; + delete d->StatusFile; + delete d; } /*}}}*/ // System::Lock - Get the lock /*{{{*/ @@ -54,16 +64,16 @@ debSystem::~debSystem() bool debSystem::Lock() { // Disable file locking - if (_config->FindB("Debug::NoLocking",false) == true || LockCount > 1) + if (_config->FindB("Debug::NoLocking",false) == true || d->LockCount > 1) { - LockCount++; + d->LockCount++; return true; } // Create the lockfile string AdminDir = flNotFile(_config->Find("Dir::State::status")); - LockFD = GetLock(AdminDir + "lock"); - if (LockFD == -1) + d->LockFD = GetLock(AdminDir + "lock"); + if (d->LockFD == -1) { if (errno == EACCES || errno == EAGAIN) return _error->Error(_("Unable to lock the administration directory (%s), " @@ -76,8 +86,8 @@ bool debSystem::Lock() // See if we need to abort with a dirty journal if (CheckUpdates() == true) { - close(LockFD); - LockFD = -1; + close(d->LockFD); + d->LockFD = -1; const char *cmd; if (getenv("SUDO_USER") != NULL) cmd = "sudo dpkg --configure -a"; @@ -89,7 +99,7 @@ bool debSystem::Lock() "run '%s' to correct the problem. "), cmd); } - LockCount++; + d->LockCount++; return true; } @@ -99,15 +109,15 @@ bool debSystem::Lock() /* */ bool debSystem::UnLock(bool NoErrors) { - if (LockCount == 0 && NoErrors == true) + if (d->LockCount == 0 && NoErrors == true) return false; - if (LockCount < 1) + if (d->LockCount < 1) return _error->Error(_("Not locked")); - if (--LockCount == 0) + if (--d->LockCount == 0) { - close(LockFD); - LockCount = 0; + close(d->LockFD); + d->LockCount = 0; } return true; @@ -168,9 +178,9 @@ bool debSystem::Initialize(Configuration &Cnf) Cnf.CndSet("Dir::State::status","/var/lib/dpkg/status"); Cnf.CndSet("Dir::Bin::dpkg","/usr/bin/dpkg"); - if (StatusFile) { - delete StatusFile; - StatusFile = 0; + if (d->StatusFile) { + delete d->StatusFile; + d->StatusFile = 0; } return true; @@ -208,9 +218,9 @@ signed debSystem::Score(Configuration const &Cnf) /* */ bool debSystem::AddStatusFiles(vector<pkgIndexFile *> &List) { - if (StatusFile == 0) - StatusFile = new debStatusIndex(_config->FindFile("Dir::State::status")); - List.push_back(StatusFile); + if (d->StatusFile == 0) + d->StatusFile = new debStatusIndex(_config->FindFile("Dir::State::status")); + List.push_back(d->StatusFile); return true; } /*}}}*/ @@ -220,11 +230,11 @@ bool debSystem::AddStatusFiles(vector<pkgIndexFile *> &List) bool debSystem::FindIndex(pkgCache::PkgFileIterator File, pkgIndexFile *&Found) const { - if (StatusFile == 0) + if (d->StatusFile == 0) return false; - if (StatusFile->FindInCache(*File.Cache()) == File) + if (d->StatusFile->FindInCache(*File.Cache()) == File) { - Found = StatusFile; + Found = d->StatusFile; return true; } diff --git a/apt-pkg/deb/debsystem.h b/apt-pkg/deb/debsystem.h index 5f9995e5d..232155256 100644 --- a/apt-pkg/deb/debsystem.h +++ b/apt-pkg/deb/debsystem.h @@ -12,16 +12,15 @@ #include <apt-pkg/pkgsystem.h> +class debSystemPrivate; + class debStatusIndex; class debSystem : public pkgSystem { - // For locking support - int LockFD; - unsigned LockCount; + // private d-pointer + debSystemPrivate *d; bool CheckUpdates(); - - debStatusIndex *StatusFile; - + public: virtual bool Lock(); @@ -35,7 +34,7 @@ class debSystem : public pkgSystem pkgIndexFile *&Found) const; debSystem(); - ~debSystem(); + virtual ~debSystem(); }; extern debSystem debSys; diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 46f48777c..61927ff68 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -26,7 +26,6 @@ #include <sys/wait.h> #include <signal.h> #include <errno.h> -#include <string.h> #include <stdio.h> #include <string.h> #include <algorithm> @@ -46,6 +45,21 @@ using namespace std; +class pkgDPkgPMPrivate +{ +public: + pkgDPkgPMPrivate() : dpkgbuf_pos(0), term_out(NULL), history_out(NULL) + { + } + bool stdin_is_dev_null; + // the buffer we use for the dpkg status-fd reading + char dpkgbuf[1024]; + int dpkgbuf_pos; + FILE *term_out; + FILE *history_out; + string dpkg_error; +}; + namespace { // Maps the dpkg "processing" info to human readable names. Entry 0 @@ -110,9 +124,9 @@ ionice(int PID) // --------------------------------------------------------------------- /* */ pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) - : pkgPackageManager(Cache), dpkgbuf_pos(0), - term_out(NULL), history_out(NULL), PackagesDone(0), PackagesTotal(0) + : pkgPackageManager(Cache), PackagesDone(0), PackagesTotal(0) { + d = new pkgDPkgPMPrivate(); } /*}}}*/ // DPkgPM::pkgDPkgPM - Destructor /*{{{*/ @@ -120,6 +134,7 @@ pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) /* */ pkgDPkgPM::~pkgDPkgPM() { + delete d; } /*}}}*/ // DPkgPM::Install - Install a package /*{{{*/ @@ -376,7 +391,7 @@ void pkgDPkgPM::DoStdin(int master) if (len) write(master, input_buf, len); else - stdin_is_dev_null = true; + d->stdin_is_dev_null = true; } /*}}}*/ // DPkgPM::DoTerminalPty - Read the terminal pty and write log /*{{{*/ @@ -401,8 +416,8 @@ void pkgDPkgPM::DoTerminalPty(int master) if(len <= 0) return; write(1, term_buf, len); - if(term_out) - fwrite(term_buf, len, sizeof(char), term_out); + if(d->term_out) + fwrite(term_buf, len, sizeof(char), d->term_out); } /*}}}*/ // DPkgPM::ProcessDpkgStatusBuf /*{{{*/ @@ -606,14 +621,14 @@ void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd) char *p, *q; int len; - len=read(statusfd, &dpkgbuf[dpkgbuf_pos], sizeof(dpkgbuf)-dpkgbuf_pos); - dpkgbuf_pos += len; + len=read(statusfd, &d->dpkgbuf[d->dpkgbuf_pos], sizeof(d->dpkgbuf)-d->dpkgbuf_pos); + d->dpkgbuf_pos += len; if(len <= 0) return; // process line by line if we have a buffer - p = q = dpkgbuf; - while((q=(char*)memchr(p, '\n', dpkgbuf+dpkgbuf_pos-p)) != NULL) + p = q = d->dpkgbuf; + while((q=(char*)memchr(p, '\n', d->dpkgbuf+d->dpkgbuf_pos-p)) != NULL) { *q = 0; ProcessDpkgStatusLine(OutStatusFd, p); @@ -621,8 +636,8 @@ void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd) } // now move the unprocessed bits (after the final \n that is now a 0x0) - // to the start and update dpkgbuf_pos - p = (char*)memrchr(dpkgbuf, 0, dpkgbuf_pos); + // to the start and update d->dpkgbuf_pos + p = (char*)memrchr(d->dpkgbuf, 0, d->dpkgbuf_pos); if(p == NULL) return; @@ -630,8 +645,8 @@ void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd) p++; // move the unprocessed tail to the start and update pos - memmove(dpkgbuf, p, p-dpkgbuf); - dpkgbuf_pos = dpkgbuf+dpkgbuf_pos-p; + memmove(d->dpkgbuf, p, p-d->dpkgbuf); + d->dpkgbuf_pos = d->dpkgbuf+d->dpkgbuf_pos-p; } /*}}}*/ // DPkgPM::WriteHistoryTag /*{{{*/ @@ -643,7 +658,7 @@ void pkgDPkgPM::WriteHistoryTag(string const &tag, string value) // poor mans rstrip(", ") if (value[length-2] == ',' && value[length-1] == ' ') value.erase(length - 2, 2); - fprintf(history_out, "%s: %s\n", tag.c_str(), value.c_str()); + fprintf(d->history_out, "%s: %s\n", tag.c_str(), value.c_str()); } /*}}}*/ // DPkgPM::OpenLog /*{{{*/ bool pkgDPkgPM::OpenLog() @@ -664,11 +679,11 @@ bool pkgDPkgPM::OpenLog() _config->Find("Dir::Log::Terminal")); if (!logfile_name.empty()) { - term_out = fopen(logfile_name.c_str(),"a"); - if (term_out == NULL) + d->term_out = fopen(logfile_name.c_str(),"a"); + if (d->term_out == NULL) return _error->WarningE("OpenLog", _("Could not open file '%s'"), logfile_name.c_str()); - setvbuf(term_out, NULL, _IONBF, 0); - SetCloseExec(fileno(term_out), true); + setvbuf(d->term_out, NULL, _IONBF, 0); + SetCloseExec(fileno(d->term_out), true); struct passwd *pw; struct group *gr; pw = getpwnam("root"); @@ -676,7 +691,7 @@ bool pkgDPkgPM::OpenLog() if (pw != NULL && gr != NULL) chown(logfile_name.c_str(), pw->pw_uid, gr->gr_gid); chmod(logfile_name.c_str(), 0644); - fprintf(term_out, "\nLog started: %s\n", timestr); + fprintf(d->term_out, "\nLog started: %s\n", timestr); } // write your history @@ -684,11 +699,11 @@ bool pkgDPkgPM::OpenLog() _config->Find("Dir::Log::History")); if (!history_name.empty()) { - history_out = fopen(history_name.c_str(),"a"); - if (history_out == NULL) + d->history_out = fopen(history_name.c_str(),"a"); + if (d->history_out == NULL) return _error->WarningE("OpenLog", _("Could not open file '%s'"), history_name.c_str()); chmod(history_name.c_str(), 0644); - fprintf(history_out, "\nStart-Date: %s\n", timestr); + fprintf(d->history_out, "\nStart-Date: %s\n", timestr); string remove, purge, install, reinstall, upgrade, downgrade; for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) { @@ -729,7 +744,7 @@ bool pkgDPkgPM::OpenLog() WriteHistoryTag("Downgrade",downgrade); WriteHistoryTag("Remove",remove); WriteHistoryTag("Purge",purge); - fflush(history_out); + fflush(d->history_out); } return true; @@ -743,16 +758,16 @@ bool pkgDPkgPM::CloseLog() struct tm *tmp = localtime(&t); strftime(timestr, sizeof(timestr), "%F %T", tmp); - if(term_out) + if(d->term_out) { - fprintf(term_out, "Log ended: "); - fprintf(term_out, "%s", timestr); - fprintf(term_out, "\n"); - fclose(term_out); + fprintf(d->term_out, "Log ended: "); + fprintf(d->term_out, "%s", timestr); + fprintf(d->term_out, "\n"); + fclose(d->term_out); } - term_out = NULL; + d->term_out = NULL; - if(history_out) + if(d->history_out) { if (disappearedPkgs.empty() == false) { @@ -769,12 +784,12 @@ bool pkgDPkgPM::CloseLog() } WriteHistoryTag("Disappeared", disappear); } - if (dpkg_error.empty() == false) - fprintf(history_out, "Error: %s\n", dpkg_error.c_str()); - fprintf(history_out, "End-Date: %s\n", timestr); - fclose(history_out); + if (d->dpkg_error.empty() == false) + fprintf(d->history_out, "Error: %s\n", d->dpkg_error.c_str()); + fprintf(d->history_out, "End-Date: %s\n", timestr); + fclose(d->history_out); } - history_out = NULL; + d->history_out = NULL; return true; } @@ -882,7 +897,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) } } - stdin_is_dev_null = false; + d->stdin_is_dev_null = false; // create log OpenLog(); @@ -1082,8 +1097,8 @@ bool pkgDPkgPM::Go(int OutStatusFd) const char *s = _("Can not write log, openpty() " "failed (/dev/pts not mounted?)\n"); fprintf(stderr, "%s",s); - if(term_out) - fprintf(term_out, "%s",s); + if(d->term_out) + fprintf(d->term_out, "%s",s); master = slave = -1; } else { struct termios rtt; @@ -1213,7 +1228,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) // wait for input or output here FD_ZERO(&rfds); - if (master >= 0 && !stdin_is_dev_null) + if (master >= 0 && !d->stdin_is_dev_null) FD_SET(0, &rfds); FD_SET(_dpkgin, &rfds); if(master >= 0) @@ -1267,14 +1282,14 @@ bool pkgDPkgPM::Go(int OutStatusFd) RunScripts("DPkg::Post-Invoke"); if (WIFSIGNALED(Status) != 0 && WTERMSIG(Status) == SIGSEGV) - strprintf(dpkg_error, "Sub-process %s received a segmentation fault.",Args[0]); + strprintf(d->dpkg_error, "Sub-process %s received a segmentation fault.",Args[0]); else if (WIFEXITED(Status) != 0) - strprintf(dpkg_error, "Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status)); + strprintf(d->dpkg_error, "Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status)); else - strprintf(dpkg_error, "Sub-process %s exited unexpectedly",Args[0]); + strprintf(d->dpkg_error, "Sub-process %s exited unexpectedly",Args[0]); - if(dpkg_error.size() > 0) - _error->Error("%s", dpkg_error.c_str()); + if(d->dpkg_error.size() > 0) + _error->Error("%s", d->dpkg_error.c_str()); if(stopOnError) { @@ -1326,7 +1341,7 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) string::size_type pos; FILE *report; - if (_config->FindB("Dpkg::ApportFailureReport", false) == false) + if (_config->FindB("Dpkg::ApportFailureReport", true) == false) { std::clog << "configured to not write apport reports" << std::endl; return; @@ -1353,18 +1368,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<string> 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<string>::iterator I = io_errors.begin(); I != io_errors.end(); I++) + { + vector<string> 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('_'); @@ -1438,8 +1484,8 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) fprintf(report, "ErrorMessage:\n %s\n", errormsg); // ensure that the log is flushed - if(term_out) - fflush(term_out); + if(d->term_out) + fflush(d->term_out); // attach terminal log it if we have it string logfile_name = _config->FindFile("Dir::Log::Terminal"); @@ -1454,6 +1500,24 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) { 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); } } diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index b7b5a6def..ddf9485c7 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -18,19 +18,12 @@ using std::vector; using std::map; +class pkgDPkgPMPrivate; class pkgDPkgPM : public pkgPackageManager { private: - - bool stdin_is_dev_null; - - // the buffer we use for the dpkg status-fd reading - char dpkgbuf[1024]; - int dpkgbuf_pos; - FILE *term_out; - FILE *history_out; - string dpkg_error; + pkgDPkgPMPrivate *d; /** \brief record the disappear action and handle accordingly diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 580056687..9104c5d56 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -406,60 +406,8 @@ bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res) /*}}}*/ // DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/ // --------------------------------------------------------------------- -/* Call with Mult = -1 to preform the inverse opration - The Mult increases the complexity of the calulations here and is unused - - or do we really have a usecase for removing the size of a package two - times? So let us replace it with a simple bool and be done with it… */ -__deprecated void pkgDepCache::AddSizes(const PkgIterator &Pkg,signed long Mult) -{ - StateCache &P = PkgState[Pkg->ID]; - - if (Pkg->VersionList == 0) - return; - - if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure && - P.Keep() == true) - return; - - // Compute the size data - if (P.NewInstall() == true) - { - iUsrSize += (signed long long)(Mult*P.InstVerIter(*this)->InstalledSize); - iDownloadSize += (signed long long)(Mult*P.InstVerIter(*this)->Size); - return; - } - - // Upgrading - if (Pkg->CurrentVer != 0 && - (P.InstallVer != (Version *)Pkg.CurrentVer() || - (P.iFlags & ReInstall) == ReInstall) && P.InstallVer != 0) - { - iUsrSize += (signed long long)(Mult*((signed long long)P.InstVerIter(*this)->InstalledSize - - (signed long long)Pkg.CurrentVer()->InstalledSize)); - iDownloadSize += (signed long long)(Mult*P.InstVerIter(*this)->Size); - return; - } - - // Reinstall - if (Pkg.State() == pkgCache::PkgIterator::NeedsUnpack && - P.Delete() == false) - { - iDownloadSize += (signed long long)(Mult*P.InstVerIter(*this)->Size); - return; - } - - // Removing - if (Pkg->CurrentVer != 0 && P.InstallVer == 0) - { - iUsrSize -= (signed long long)(Mult*Pkg.CurrentVer()->InstalledSize); - return; - } -} - /*}}}*/ -// DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/ -// --------------------------------------------------------------------- /* Call with Inverse = true to preform the inverse opration */ -void pkgDepCache::AddSizes(const PkgIterator &Pkg, bool const &Inverse) +void pkgDepCache::AddSizes(const PkgIterator &Pkg, bool const Inverse) { StateCache &P = PkgState[Pkg->ID]; @@ -530,8 +478,9 @@ void pkgDepCache::AddSizes(const PkgIterator &Pkg, bool const &Inverse) calld Remove/Add itself. Remember, dependencies can be circular so while processing a dep for Pkg it is possible that Add/Remove will be called on Pkg */ -void pkgDepCache::AddStates(const PkgIterator &Pkg,int Add) +void pkgDepCache::AddStates(const PkgIterator &Pkg, bool const Invert) { + signed char const Add = (Invert == false) ? 1 : -1; StateCache &State = PkgState[Pkg->ID]; // The Package is broken (either minimal dep or policy dep) @@ -806,17 +755,17 @@ void pkgDepCache::Update(PkgIterator const &Pkg) // DepCache::MarkKeep - Put the package in the keep state /*{{{*/ // --------------------------------------------------------------------- /* */ -void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser, +bool pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser, unsigned long Depth) { if (IsModeChangeOk(ModeKeep, Pkg, Depth, FromUser) == false) - return; + return false; /* Reject an attempt to keep a non-source broken installed package, those must be upgraded */ if (Pkg.State() == PkgIterator::NeedsUnpack && Pkg.CurrentVer().Downloadable() == false) - return; + return false; /* We changed the soft state all the time so the UI is a bit nicer to use */ @@ -824,7 +773,7 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser, // Check that it is not already kept if (P.Mode == ModeKeep) - return; + return true; if (Soft == true) P.iFlags |= AutoKept; @@ -857,31 +806,31 @@ void pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser, P.InstallVer = Pkg.CurrentVer(); AddStates(Pkg); - Update(Pkg); - AddSizes(Pkg); + + return true; } /*}}}*/ // DepCache::MarkDelete - Put the package in the delete state /*{{{*/ // --------------------------------------------------------------------- /* */ -void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge, +bool pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge, unsigned long Depth, bool FromUser) { if (IsModeChangeOk(ModeDelete, Pkg, Depth, FromUser) == false) - return; + return false; StateCache &P = PkgState[Pkg->ID]; // Check that it is not already marked for delete if ((P.Mode == ModeDelete || P.InstallVer == 0) && (Pkg.Purge() == true || rPurge == false)) - return; + return true; // check if we are allowed to remove the package if (IsDeleteOk(Pkg,rPurge,Depth,FromUser) == false) - return; + return false; P.iFlags &= ~(AutoKept | Purge); if (rPurge == true) @@ -905,6 +854,7 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge, Update(Pkg); AddSizes(Pkg); + return true; } /*}}}*/ // DepCache::IsDeleteOk - check if it is ok to remove this package /*{{{*/ @@ -917,6 +867,7 @@ bool pkgDepCache::IsDeleteOk(PkgIterator const &Pkg,bool rPurge, if (FromUser == false && Pkg->CurrentVer == 0) { StateCache &P = PkgState[Pkg->ID]; + // Status == 2 means this applies for new installs only if (P.InstallVer != 0 && P.Status == 2 && (P.Flags & Flag::Auto) != Flag::Auto) { if (DebugMarker == true) @@ -985,18 +936,18 @@ bool pkgDepCache::IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg, // DepCache::MarkInstall - Put the package in the install state /*{{{*/ // --------------------------------------------------------------------- /* */ -void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, +bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, unsigned long Depth, bool FromUser, bool ForceImportantDeps) { if (IsModeChangeOk(ModeInstall, Pkg, Depth, FromUser) == false) - return; + return false; StateCache &P = PkgState[Pkg->ID]; // See if there is even any possible instalation candidate if (P.CandidateVer == 0) - return; + return false; /* Check that it is not already marked for install and that it can be installed */ @@ -1005,13 +956,13 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, P.CandidateVer == (Version *)Pkg.CurrentVer())) { if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0) - MarkKeep(Pkg, false, FromUser, Depth+1); - return; + return MarkKeep(Pkg, false, FromUser, Depth+1); + return true; } // check if we are allowed to install the package if (IsInstallOk(Pkg,AutoInst,Depth,FromUser) == false) - return; + return false; ActionGroup group(*this); P.iFlags &= ~AutoKept; @@ -1046,8 +997,8 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, Update(Pkg); AddSizes(Pkg); - if (AutoInst == false) - return; + if (AutoInst == false || _config->Find("APT::Solver", "internal") != "internal") + return true; if (DebugMarker == true) std::clog << OutputInDepth(Depth) << "MarkInstall " << Pkg << " FU=" << FromUser << std::endl; @@ -1091,7 +1042,7 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, continue; // if the dependency was critical, we can't install it, so remove it again MarkDelete(Pkg,false,Depth + 1, false); - return; + return false; } /* Check if any ImportantDep() (but not Critical) were added @@ -1222,14 +1173,17 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, continue; if (PkgState[Pkg->ID].CandidateVer != *I && - Start->Type == Dep::DpkgBreaks) - MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps); - else - MarkDelete(Pkg,false,Depth + 1, false); + Start->Type == Dep::DpkgBreaks && + MarkInstall(Pkg,true,Depth + 1, false, ForceImportantDeps) == true) + continue; + else if (MarkDelete(Pkg,false,Depth + 1, false) == false) + break; } continue; } } + + return Dep.end() == true; } /*}}}*/ // DepCache::IsInstallOk - check if it is ok to install this package /*{{{*/ @@ -1268,7 +1222,7 @@ void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To) // DepCache::SetCandidateVersion - Change the candidate version /*{{{*/ // --------------------------------------------------------------------- /* */ -void pkgDepCache::SetCandidateVersion(VerIterator TargetVer, bool const &Pseudo) +void pkgDepCache::SetCandidateVersion(VerIterator TargetVer) { pkgCache::PkgIterator Pkg = TargetVer.ParentPkg(); StateCache &P = PkgState[Pkg->ID]; @@ -1558,7 +1512,7 @@ bool pkgDepCache::Policy::IsImportantDep(DepIterator const &Dep) return true; else if(Dep->Type == pkgCache::Dep::Recommends) { - if ( _config->FindB("APT::Install-Recommends", false)) + if (InstallRecommends) return true; // we suport a special mode to only install-recommends for certain // sections @@ -1569,11 +1523,17 @@ bool pkgDepCache::Policy::IsImportantDep(DepIterator const &Dep) return true; } else if(Dep->Type == pkgCache::Dep::Suggests) - return _config->FindB("APT::Install-Suggests", false); + return InstallSuggests; return false; } /*}}}*/ +// Policy::GetPriority - Get the priority of the package pin /*{{{*/ +signed short pkgDepCache::Policy::GetPriority(pkgCache::PkgIterator const &Pkg) +{ return 0; }; +signed short pkgDepCache::Policy::GetPriority(pkgCache::PkgFileIterator const &File) +{ return 0; }; + /*}}}*/ pkgDepCache::InRootSetFunc *pkgDepCache::GetRootSetFunc() /*{{{*/ { DefaultRootSetFunc *f = new DefaultRootSetFunc; @@ -1599,6 +1559,9 @@ bool pkgDepCache::MarkFollowsSuggests() // pkgDepCache::MarkRequired - the main mark algorithm /*{{{*/ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc) { + if (_config->Find("APT::Solver", "internal") != "internal") + return true; + bool follow_recommends; bool follow_suggests; bool debug_autoremove = _config->FindB("Debug::pkgAutoRemove",false); diff --git a/apt-pkg/depcache.h b/apt-pkg/depcache.h index 760f0b589..66cb7dbab 100644 --- a/apt-pkg/depcache.h +++ b/apt-pkg/depcache.h @@ -233,6 +233,7 @@ class pkgDepCache : protected pkgCache::Namespace inline bool Delete() const {return Mode == ModeDelete;}; inline bool Purge() const {return Delete() == true && (iFlags & pkgDepCache::Purge) == pkgDepCache::Purge; }; inline bool Keep() const {return Mode == ModeKeep;}; + inline bool Protect() const {return (iFlags & Protected) == Protected;}; inline bool Upgrade() const {return Status > 0 && Mode == ModeInstall;}; inline bool Upgradable() const {return Status >= 1;}; inline bool Downgrade() const {return Status < 0 && Mode == ModeInstall;}; @@ -257,11 +258,21 @@ class pkgDepCache : protected pkgCache::Namespace class Policy { public: - + Policy() { + InstallRecommends = _config->FindB("APT::Install-Recommends", false); + InstallSuggests = _config->FindB("APT::Install-Suggests", false); + } + virtual VerIterator GetCandidateVer(PkgIterator const &Pkg); virtual bool IsImportantDep(DepIterator const &Dep); - + virtual signed short GetPriority(PkgIterator const &Pkg); + virtual signed short GetPriority(PkgFileIterator const &File); + virtual ~Policy() {}; + + private: + bool InstallRecommends; + bool InstallSuggests; }; private: @@ -315,11 +326,10 @@ class pkgDepCache : protected pkgCache::Namespace void Update(PkgIterator const &P); // Count manipulators - void AddSizes(const PkgIterator &Pkg, bool const &Invert = false); + void AddSizes(const PkgIterator &Pkg, bool const Invert = false); inline void RemoveSizes(const PkgIterator &Pkg) {AddSizes(Pkg, true);}; - void AddSizes(const PkgIterator &Pkg,signed long Mult) __deprecated; - void AddStates(const PkgIterator &Pkg,int Add = 1); - inline void RemoveStates(const PkgIterator &Pkg) {AddStates(Pkg,-1);}; + void AddStates(const PkgIterator &Pkg, bool const Invert = false); + inline void RemoveStates(const PkgIterator &Pkg) {AddStates(Pkg,true);}; public: @@ -388,18 +398,17 @@ class pkgDepCache : protected pkgCache::Namespace /** \name State Manipulators */ // @{ - void MarkKeep(PkgIterator const &Pkg, bool Soft = false, + bool MarkKeep(PkgIterator const &Pkg, bool Soft = false, bool FromUser = true, unsigned long Depth = 0); - void MarkDelete(PkgIterator const &Pkg, bool MarkPurge = false, + bool MarkDelete(PkgIterator const &Pkg, bool MarkPurge = false, unsigned long Depth = 0, bool FromUser = true); - void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true, + bool MarkInstall(PkgIterator const &Pkg,bool AutoInst = true, unsigned long Depth = 0, bool FromUser = true, bool ForceImportantDeps = false); void MarkProtected(PkgIterator const &Pkg) { PkgState[Pkg->ID].iFlags |= Protected; }; void SetReInstall(PkgIterator const &Pkg,bool To); - // FIXME: Remove the unused boolean parameter on abi break - void SetCandidateVersion(VerIterator TargetVer, bool const &Pseudo = true); + void SetCandidateVersion(VerIterator TargetVer); bool SetCandidateRelease(pkgCache::VerIterator TargetVer, std::string const &TargetRel); /** Set the candidate version for dependencies too if needed. @@ -484,13 +493,6 @@ class pkgDepCache : protected pkgCache::Namespace virtual ~pkgDepCache(); private: - // Helper for Update(OpProgress) to remove pseudoinstalled arch all packages - // FIXME: they are private so shouldn't affect abi, but just in case… - __deprecated bool RemovePseudoInstalledPkg(PkgIterator &Pkg, std::set<unsigned long> &recheck) { return true; }; - __deprecated bool ReInstallPseudoForGroup(unsigned long const &Grp, std::set<unsigned long> &recheck) { return true; }; - __deprecated bool ReInstallPseudoForGroup(pkgCache::PkgIterator const &P, std::set<unsigned long> &recheck) { return true; }; - - bool IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg, unsigned long const Depth, bool const FromUser); }; diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc new file mode 100644 index 000000000..4d2230613 --- /dev/null +++ b/apt-pkg/edsp.cc @@ -0,0 +1,564 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/* ###################################################################### + Set of methods to help writing and reading everything needed for EDSP + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include <apt-pkg/edsp.h> +#include <apt-pkg/error.h> +#include <apt-pkg/configuration.h> +#include <apt-pkg/version.h> +#include <apt-pkg/policy.h> +#include <apt-pkg/tagfile.h> + +#include <apti18n.h> +#include <limits> + +#include <stdio.h> + /*}}}*/ + +// we could use pkgCache::DepType and ::Priority, but these would be localized strings… +const char * const EDSP::PrioMap[] = {0, "important", "required", "standard", + "optional", "extra"}; +const char * const EDSP::DepMap[] = {"", "Depends", "Pre-Depends", "Suggests", + "Recommends" , "Conflicts", "Replaces", + "Obsoletes", "Breaks", "Enhances"}; + +// EDSP::WriteScenario - to the given file descriptor /*{{{*/ +bool EDSP::WriteScenario(pkgDepCache &Cache, FILE* output, OpProgress *Progress) +{ + if (Progress != NULL) + Progress->SubProgress(Cache.Head().VersionCount, _("Send scenario to solver")); + unsigned long p = 0; + for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg) + for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver, ++p) + { + WriteScenarioVersion(Cache, output, Pkg, Ver); + WriteScenarioDependency(Cache, output, Pkg, Ver); + fprintf(output, "\n"); + if (Progress != NULL && p % 100 == 0) + Progress->Progress(p); + } + return true; +} + /*}}}*/ +// EDSP::WriteLimitedScenario - to the given file descriptor /*{{{*/ +bool EDSP::WriteLimitedScenario(pkgDepCache &Cache, FILE* output, + APT::PackageSet const &pkgset, + OpProgress *Progress) +{ + if (Progress != NULL) + Progress->SubProgress(Cache.Head().VersionCount, _("Send scenario to solver")); + unsigned long p = 0; + for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg, ++p) + for (pkgCache::VerIterator Ver = Pkg.VersionList(); Ver.end() == false; ++Ver) + { + WriteScenarioVersion(Cache, output, Pkg, Ver); + WriteScenarioLimitedDependency(Cache, output, Pkg, Ver, pkgset); + fprintf(output, "\n"); + if (Progress != NULL && p % 100 == 0) + Progress->Progress(p); + } + if (Progress != NULL) + Progress->Done(); + return true; +} + /*}}}*/ +// EDSP::WriteScenarioVersion /*{{{*/ +void EDSP::WriteScenarioVersion(pkgDepCache &Cache, FILE* output, pkgCache::PkgIterator const &Pkg, + pkgCache::VerIterator const &Ver) +{ + fprintf(output, "Package: %s\n", Pkg.Name()); + fprintf(output, "Architecture: %s\n", Ver.Arch()); + fprintf(output, "Version: %s\n", Ver.VerStr()); + if (Pkg.CurrentVer() == Ver) + fprintf(output, "Installed: yes\n"); + if (Pkg->SelectedState == pkgCache::State::Hold || + (Cache[Pkg].Keep() == true && Cache[Pkg].Protect() == true)) + fprintf(output, "Hold: yes\n"); + fprintf(output, "APT-ID: %d\n", Ver->ID); + fprintf(output, "Priority: %s\n", PrioMap[Ver->Priority]); + if ((Pkg->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) + fprintf(output, "Essential: yes\n"); + fprintf(output, "Section: %s\n", Ver.Section()); + if ((Ver->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed) + fprintf(output, "Multi-Arch: allowed\n"); + else if ((Ver->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign) + fprintf(output, "Multi-Arch: foreign\n"); + else if ((Ver->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same) + fprintf(output, "Multi-Arch: same\n"); + signed short Pin = std::numeric_limits<signed short>::min(); + for (pkgCache::VerFileIterator File = Ver.FileList(); File.end() == false; ++File) { + signed short const p = Cache.GetPolicy().GetPriority(File.File()); + if (Pin < p) + Pin = p; + } + fprintf(output, "APT-Pin: %d\n", Pin); + if (Cache.GetCandidateVer(Pkg) == Ver) + fprintf(output, "APT-Candidate: yes\n"); + if ((Cache[Pkg].Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto) + fprintf(output, "APT-Automatic: yes\n"); +} + /*}}}*/ +// EDSP::WriteScenarioDependency /*{{{*/ +void EDSP::WriteScenarioDependency(pkgDepCache &Cache, FILE* output, pkgCache::PkgIterator const &Pkg, + pkgCache::VerIterator const &Ver) +{ + std::string dependencies[pkgCache::Dep::Enhances + 1]; + bool orGroup = false; + for (pkgCache::DepIterator Dep = Ver.DependsList(); Dep.end() == false; ++Dep) + { + // Ignore implicit dependencies for multiarch here + if (strcmp(Pkg.Arch(), Dep.TargetPkg().Arch()) != 0) + continue; + if (orGroup == false) + dependencies[Dep->Type].append(", "); + dependencies[Dep->Type].append(Dep.TargetPkg().Name()); + if (Dep->Version != 0) + dependencies[Dep->Type].append(" (").append(pkgCache::CompTypeDeb(Dep->CompareOp)).append(" ").append(Dep.TargetVer()).append(")"); + if ((Dep->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or) + { + dependencies[Dep->Type].append(" | "); + orGroup = true; + } + else + orGroup = false; + } + for (int i = 1; i < pkgCache::Dep::Enhances + 1; ++i) + if (dependencies[i].empty() == false) + fprintf(output, "%s: %s\n", DepMap[i], dependencies[i].c_str()+2); + string provides; + for (pkgCache::PrvIterator Prv = Ver.ProvidesList(); Prv.end() == false; ++Prv) + { + // Ignore implicit provides for multiarch here + if (strcmp(Pkg.Arch(), Prv.ParentPkg().Arch()) != 0 || strcmp(Pkg.Name(),Prv.Name()) == 0) + continue; + provides.append(", ").append(Prv.Name()); + } + if (provides.empty() == false) + fprintf(output, "Provides: %s\n", provides.c_str()+2); +} + /*}}}*/ +// EDSP::WriteScenarioLimitedDependency /*{{{*/ +void EDSP::WriteScenarioLimitedDependency(pkgDepCache &Cache, FILE* output, + pkgCache::PkgIterator const &Pkg, + pkgCache::VerIterator const &Ver, + APT::PackageSet const &pkgset) +{ + std::string dependencies[pkgCache::Dep::Enhances + 1]; + bool orGroup = false; + for (pkgCache::DepIterator Dep = Ver.DependsList(); Dep.end() == false; ++Dep) + { + // Ignore implicit dependencies for multiarch here + if (strcmp(Pkg.Arch(), Dep.TargetPkg().Arch()) != 0) + continue; + if (orGroup == false) + { + if (pkgset.find(Dep.TargetPkg()) == pkgset.end()) + continue; + dependencies[Dep->Type].append(", "); + } + else if (pkgset.find(Dep.TargetPkg()) == pkgset.end()) + { + if ((Dep->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or) + continue; + dependencies[Dep->Type].erase(dependencies[Dep->Type].end()-3, dependencies[Dep->Type].end()); + orGroup = false; + continue; + } + dependencies[Dep->Type].append(Dep.TargetPkg().Name()); + if (Dep->Version != 0) + dependencies[Dep->Type].append(" (").append(pkgCache::CompTypeDeb(Dep->CompareOp)).append(" ").append(Dep.TargetVer()).append(")"); + if ((Dep->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or) + { + dependencies[Dep->Type].append(" | "); + orGroup = true; + } + else + orGroup = false; + } + for (int i = 1; i < pkgCache::Dep::Enhances + 1; ++i) + if (dependencies[i].empty() == false) + fprintf(output, "%s: %s\n", DepMap[i], dependencies[i].c_str()+2); + string provides; + for (pkgCache::PrvIterator Prv = Ver.ProvidesList(); Prv.end() == false; ++Prv) + { + // Ignore implicit provides for multiarch here + if (strcmp(Pkg.Arch(), Prv.ParentPkg().Arch()) != 0 || strcmp(Pkg.Name(),Prv.Name()) == 0) + continue; + if (pkgset.find(Prv.ParentPkg()) == pkgset.end()) + continue; + provides.append(", ").append(Prv.Name()); + } + if (provides.empty() == false) + fprintf(output, "Provides: %s\n", provides.c_str()+2); +} + /*}}}*/ +// EDSP::WriteRequest - to the given file descriptor /*{{{*/ +bool EDSP::WriteRequest(pkgDepCache &Cache, FILE* output, bool const Upgrade, + bool const DistUpgrade, bool const AutoRemove, + OpProgress *Progress) +{ + if (Progress != NULL) + Progress->SubProgress(Cache.Head().PackageCount, _("Send request to solver")); + unsigned long p = 0; + string del, inst; + for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg, ++p) + { + if (Progress != NULL && p % 100 == 0) + Progress->Progress(p); + string* req; + if (Cache[Pkg].Delete() == true) + req = &del; + else if (Cache[Pkg].NewInstall() == true || Cache[Pkg].Upgrade() == true) + req = &inst; + else + continue; + req->append(" ").append(Pkg.FullName()); + } + fprintf(output, "Request: EDSP 0.4\n"); + if (del.empty() == false) + fprintf(output, "Remove: %s\n", del.c_str()+1); + if (inst.empty() == false) + fprintf(output, "Install: %s\n", inst.c_str()+1); + if (Upgrade == true) + fprintf(output, "Upgrade: yes\n"); + if (DistUpgrade == true) + fprintf(output, "Dist-Upgrade: yes\n"); + if (AutoRemove == true) + fprintf(output, "Autoremove: yes\n"); + if (_config->FindB("APT::Solver::Strict-Pinning", true) == false) + fprintf(output, "Strict-Pinning: no\n"); + string solverpref("APT::Solver::"); + solverpref.append(_config->Find("APT::Solver", "internal")).append("::Preferences"); + if (_config->Exists(solverpref) == true) + fprintf(output, "Preferences: %s\n", _config->Find(solverpref,"").c_str()); + fprintf(output, "\n"); + + return true; +} + /*}}}*/ +// EDSP::ReadResponse - from the given file descriptor /*{{{*/ +bool EDSP::ReadResponse(int const input, pkgDepCache &Cache, OpProgress *Progress) { + /* We build an map id to mmap offset here + In theory we could use the offset as ID, but then VersionCount + couldn't be used to create other versionmappings anymore and it + would be too easy for a (buggy) solver to segfault APT… */ + unsigned long long const VersionCount = Cache.Head().VersionCount; + unsigned long VerIdx[VersionCount]; + for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; ++P) { + for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; ++V) + VerIdx[V->ID] = V.Index(); + Cache[P].Marked = true; + Cache[P].Garbage = false; + } + + FileFd in; + in.OpenDescriptor(input, FileFd::ReadOnly); + pkgTagFile response(&in, 100); + pkgTagSection section; + + while (response.Step(section) == true) { + std::string type; + if (section.Exists("Install") == true) + type = "Install"; + else if (section.Exists("Remove") == true) + type = "Remove"; + else if (section.Exists("Progress") == true) { + if (Progress != NULL) { + string msg = section.FindS("Message"); + if (msg.empty() == true) + msg = _("Prepare for receiving solution"); + Progress->SubProgress(100, msg, section.FindI("Percentage", 0)); + } + continue; + } else if (section.Exists("Error") == true) { + std::string msg = SubstVar(SubstVar(section.FindS("Message"), "\n .\n", "\n\n"), "\n ", "\n"); + if (msg.empty() == true) { + msg = _("External solver failed without a proper error message"); + _error->Error(msg.c_str()); + } else + _error->Error("External solver failed with: %s", msg.substr(0,msg.find('\n')).c_str()); + if (Progress != NULL) + Progress->Done(); + std::cerr << "The solver encountered an error of type: " << section.FindS("Error") << std::endl; + std::cerr << "The following information might help you to understand what is wrong:" << std::endl; + std::cerr << msg << std::endl << std::endl; + return false; + } else if (section.Exists("Autoremove") == true) + type = "Autoremove"; + else + continue; + + size_t const id = section.FindULL(type.c_str(), VersionCount); + if (id == VersionCount) { + _error->Warning("Unable to parse %s request with id value '%s'!", type.c_str(), section.FindS(type.c_str()).c_str()); + continue; + } else if (id > Cache.Head().VersionCount) { + _error->Warning("ID value '%s' in %s request stanza is to high to refer to a known version!", section.FindS(type.c_str()).c_str(), type.c_str()); + continue; + } + + pkgCache::VerIterator Ver(Cache.GetCache(), Cache.GetCache().VerP + VerIdx[id]); + Cache.SetCandidateVersion(Ver); + if (type == "Install") + Cache.MarkInstall(Ver.ParentPkg(), false, 0, false); + else if (type == "Remove") + Cache.MarkDelete(Ver.ParentPkg(), false); + else if (type == "Autoremove") { + Cache[Ver.ParentPkg()].Marked = false; + Cache[Ver.ParentPkg()].Garbage = true; + } + } + return true; +} + /*}}}*/ +// EDSP::ReadLine - first line from the given file descriptor /*{{{*/ +// --------------------------------------------------------------------- +/* Little helper method to read a complete line into a string. Similar to + fgets but we need to use the low-level read() here as otherwise the + listparser will be confused later on as mixing of fgets and read isn't + a supported action according to the manpages and results are undefined */ +bool EDSP::ReadLine(int const input, std::string &line) { + char one; + ssize_t data = 0; + line.erase(); + line.reserve(100); + while ((data = read(input, &one, sizeof(one))) != -1) { + if (data != 1) + continue; + if (one == '\n') + return true; + if (one == '\r') + continue; + if (line.empty() == true && isblank(one) != 0) + continue; + line += one; + } + return false; +} + /*}}}*/ +// EDSP::StringToBool - convert yes/no to bool /*{{{*/ +// --------------------------------------------------------------------- +/* we are not as lazy as we are in the global StringToBool as we really + only accept yes/no here - but we will ignore leading spaces */ +bool EDSP::StringToBool(char const *answer, bool const defValue) { + for (; isspace(*answer) != 0; ++answer); + if (strncasecmp(answer, "yes", 3) == 0) + return true; + else if (strncasecmp(answer, "no", 2) == 0) + return false; + else + _error->Warning("Value '%s' is not a boolean 'yes' or 'no'!", answer); + return defValue; +} + /*}}}*/ +// EDSP::ReadRequest - first stanza from the given file descriptor /*{{{*/ +bool EDSP::ReadRequest(int const input, std::list<std::string> &install, + std::list<std::string> &remove, bool &upgrade, + bool &distUpgrade, bool &autoRemove) +{ + install.clear(); + remove.clear(); + upgrade = false; + distUpgrade = false; + autoRemove = false; + std::string line; + while (ReadLine(input, line) == true) + { + // Skip empty lines before request + if (line.empty() == true) + continue; + // The first Tag must be a request, so search for it + if (line.compare(0, 8, "Request:") != 0) + continue; + + while (ReadLine(input, line) == true) + { + // empty lines are the end of the request + if (line.empty() == true) + return true; + + std::list<std::string> *request = NULL; + if (line.compare(0, 8, "Install:") == 0) + { + line.erase(0, 8); + request = &install; + } + else if (line.compare(0, 7, "Remove:") == 0) + { + line.erase(0, 7); + request = &remove; + } + else if (line.compare(0, 8, "Upgrade:") == 0) + upgrade = EDSP::StringToBool(line.c_str() + 9, false); + else if (line.compare(0, 13, "Dist-Upgrade:") == 0) + distUpgrade = EDSP::StringToBool(line.c_str() + 14, false); + else if (line.compare(0, 11, "Autoremove:") == 0) + autoRemove = EDSP::StringToBool(line.c_str() + 12, false); + else + _error->Warning("Unknown line in EDSP Request stanza: %s", line.c_str()); + + if (request == NULL) + continue; + size_t end = line.length(); + do { + size_t begin = line.rfind(' '); + if (begin == std::string::npos) + { + request->push_back(line.substr(0, end)); + break; + } + else if (begin < end) + request->push_back(line.substr(begin + 1, end)); + line.erase(begin); + end = line.find_last_not_of(' '); + } while (end != std::string::npos); + } + } + return false; +} + /*}}}*/ +// EDSP::ApplyRequest - first stanza from the given file descriptor /*{{{*/ +bool EDSP::ApplyRequest(std::list<std::string> const &install, + std::list<std::string> const &remove, + pkgDepCache &Cache) +{ + for (std::list<std::string>::const_iterator i = install.begin(); + i != install.end(); ++i) { + pkgCache::PkgIterator P = Cache.FindPkg(*i); + if (P.end() == true) + _error->Warning("Package %s is not known, so can't be installed", i->c_str()); + else + Cache.MarkInstall(P, false); + } + + for (std::list<std::string>::const_iterator i = remove.begin(); + i != remove.end(); ++i) { + pkgCache::PkgIterator P = Cache.FindPkg(*i); + if (P.end() == true) + _error->Warning("Package %s is not known, so can't be installed", i->c_str()); + else + Cache.MarkDelete(P); + } + return true; +} + /*}}}*/ +// EDSP::WriteSolution - to the given file descriptor /*{{{*/ +bool EDSP::WriteSolution(pkgDepCache &Cache, FILE* output) +{ + bool const Debug = _config->FindB("Debug::EDSP::WriteSolution", false); + for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg) + { + if (Cache[Pkg].Delete() == true) + { + fprintf(output, "Remove: %d\n", Pkg.CurrentVer()->ID); + if (Debug == true) + fprintf(output, "Package: %s\nVersion: %s\n", Pkg.FullName().c_str(), Pkg.CurrentVer().VerStr()); + } + else if (Cache[Pkg].NewInstall() == true || Cache[Pkg].Upgrade() == true) + { + fprintf(output, "Install: %d\n", Cache.GetCandidateVer(Pkg)->ID); + if (Debug == true) + fprintf(output, "Package: %s\nVersion: %s\n", Pkg.FullName().c_str(), Cache.GetCandidateVer(Pkg).VerStr()); + } + else if (Cache[Pkg].Garbage == true) + { + fprintf(output, "Autoremove: %d\n", Pkg.CurrentVer()->ID); + if (Debug == true) + fprintf(output, "Package: %s\nVersion: %s\n", Pkg.FullName().c_str(), Pkg.CurrentVer().VerStr()); + fprintf(stderr, "Autoremove: %s\nVersion: %s\n", Pkg.FullName().c_str(), Pkg.CurrentVer().VerStr()); + } + else + continue; + fprintf(output, "\n"); + } + + return true; +} + /*}}}*/ +// EDSP::WriteProgess - pulse to the given file descriptor /*{{{*/ +bool EDSP::WriteProgress(unsigned short const percent, const char* const message, FILE* output) { + fprintf(output, "Progress: %s\n", TimeRFC1123(time(NULL)).c_str()); + fprintf(output, "Percentage: %d\n", percent); + fprintf(output, "Message: %s\n\n", message); + fflush(output); + return true; +} + /*}}}*/ +// EDSP::WriteError - format an error message to be send to file descriptor /*{{{*/ +bool EDSP::WriteError(char const * const uuid, std::string const &message, FILE* output) { + fprintf(output, "Error: %s\n", uuid); + fprintf(output, "Message: %s\n\n", SubstVar(SubstVar(message, "\n\n", "\n.\n"), "\n", "\n ").c_str()); + return true; +} + /*}}}*/ +// EDSP::ExecuteSolver - fork requested solver and setup ipc pipes {{{*/ +bool EDSP::ExecuteSolver(const char* const solver, int *solver_in, int *solver_out) { + std::vector<std::string> const solverDirs = _config->FindVector("Dir::Bin::Solvers"); + std::string file; + for (std::vector<std::string>::const_iterator dir = solverDirs.begin(); + dir != solverDirs.end(); ++dir) { + file = flCombine(*dir, solver); + if (RealFileExists(file.c_str()) == true) + break; + file.clear(); + } + + if (file.empty() == true) + return _error->Error("Can't call external solver '%s' as it is not in a configured directory!", solver); + int external[4] = {-1, -1, -1, -1}; + if (pipe(external) != 0 || pipe(external + 2) != 0) + return _error->Errno("Resolve", "Can't create needed IPC pipes for EDSP"); + for (int i = 0; i < 4; ++i) + SetCloseExec(external[i], true); + + pid_t Solver = ExecFork(); + if (Solver == 0) { + dup2(external[0], STDIN_FILENO); + dup2(external[3], STDOUT_FILENO); + const char* calling[2] = { file.c_str(), 0 }; + execv(calling[0], (char**) calling); + std::cerr << "Failed to execute solver '" << solver << "'!" << std::endl; + _exit(100); + } + close(external[0]); + close(external[3]); + + if (WaitFd(external[1], true, 5) == false) + return _error->Errno("Resolve", "Timed out while Waiting on availability of solver stdin"); + + *solver_in = external[1]; + *solver_out = external[2]; + return true; +} + /*}}}*/ +// EDSP::ResolveExternal - resolve problems by asking external for help {{{*/ +bool EDSP::ResolveExternal(const char* const solver, pkgDepCache &Cache, + bool const upgrade, bool const distUpgrade, + bool const autoRemove, OpProgress *Progress) { + int solver_in, solver_out; + if (EDSP::ExecuteSolver(solver, &solver_in, &solver_out) == false) + return false; + + FILE* output = fdopen(solver_in, "w"); + if (output == NULL) + return _error->Errno("Resolve", "fdopen on solver stdin failed"); + + if (Progress != NULL) + Progress->OverallProgress(0, 100, 5, _("Execute external solver")); + EDSP::WriteRequest(Cache, output, upgrade, distUpgrade, autoRemove, Progress); + if (Progress != NULL) + Progress->OverallProgress(5, 100, 20, _("Execute external solver")); + EDSP::WriteScenario(Cache, output, Progress); + fclose(output); + + if (Progress != NULL) + Progress->OverallProgress(25, 100, 75, _("Execute external solver")); + if (EDSP::ReadResponse(solver_out, Cache, Progress) == false) + return false; + + return true; +} + /*}}}*/ diff --git a/apt-pkg/edsp.h b/apt-pkg/edsp.h new file mode 100644 index 000000000..743c3f5d1 --- /dev/null +++ b/apt-pkg/edsp.h @@ -0,0 +1,222 @@ +// -*- mode: cpp; mode: fold -*- +/** 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 + a Cache as this is handled by edsp interface for listparser and friends + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_EDSP_H +#define PKGLIB_EDSP_H + +#include <apt-pkg/depcache.h> +#include <apt-pkg/cacheset.h> +#include <apt-pkg/progress.h> + +#include <string> + +class EDSP /*{{{*/ +{ + // we could use pkgCache::DepType and ::Priority, but these would be localized strings… + static const char * const PrioMap[]; + static const char * const DepMap[]; + + bool static ReadLine(int const input, std::string &line); + bool static StringToBool(char const *answer, bool const defValue); + + void static WriteScenarioVersion(pkgDepCache &Cache, FILE* output, + pkgCache::PkgIterator const &Pkg, + pkgCache::VerIterator const &Ver); + void static WriteScenarioDependency(pkgDepCache &Cache, FILE* output, + pkgCache::PkgIterator const &Pkg, + pkgCache::VerIterator const &Ver); + void static WriteScenarioLimitedDependency(pkgDepCache &Cache, FILE* output, + pkgCache::PkgIterator const &Pkg, + pkgCache::VerIterator const &Ver, + APT::PackageSet const &pkgset); +public: + /** \brief creates the EDSP request stanza + * + * In the EDSP protocol the first thing send to the resolver is a stanza + * encoding the request. This method will write this stanza by looking at + * the given Cache and requests the installation of all packages which were + * marked for installation in it (equally for remove). + * + * \param Cache in which the request is encoded + * \param output is written to this "file" + * \param upgrade is true if it is an request like apt-get upgrade + * \param distUpgrade is true if it is a request like apt-get dist-upgrade + * \param autoRemove is true if removal of unneeded packages should be performed + * \param Progress is an instance to report progress to + * + * \return true if request was composed successfully, otherwise false + */ + bool static WriteRequest(pkgDepCache &Cache, FILE* output, + bool const upgrade = false, + bool const distUpgrade = false, + bool const autoRemove = false, + OpProgress *Progress = NULL); + + /** \brief creates the scenario representing the package universe + * + * After the request all known information about a package are send + * to the solver. The output looks similar to a Packages or status file + * + * All packages and version included in this Cache are send, even if + * it doesn't make sense from an APT resolver point of view like versions + * with a negative pin to enable the solver to propose even that as a + * solution or at least to be able to give a hint what can be done to + * statisfy a request. + * + * \param Cache is the known package universe + * \param output is written to this "file" + * \param Progress is an instance to report progress to + * + * \return true if universe was composed successfully, otherwise false + */ + bool static WriteScenario(pkgDepCache &Cache, FILE* output, OpProgress *Progress = NULL); + + /** \brief creates a limited scenario representing the package universe + * + * This method works similar to #WriteScenario as it works in the same + * way but doesn't send the complete universe to the solver but only + * packages included in the pkgset which will have only dependencies + * on packages which are in the given set. All other dependencies will + * be removed, so that this method can be used to create testcases + * + * \param Cache is the known package universe + * \param output is written to this "file" + * \param pkgset is a set of packages the universe should be limited to + * \param Progress is an instance to report progress to + * + * \return true if universe was composed successfully, otherwise false + */ + bool static WriteLimitedScenario(pkgDepCache &Cache, FILE* output, + APT::PackageSet const &pkgset, + OpProgress *Progress = NULL); + + /** \brief waits and acts on the information returned from the solver + * + * This method takes care of interpreting whatever the solver sends + * through the standard output like a solution, progress or an error. + * The main thread should handle his control over to this method to + * wait for the solver to finish the given task + * + * \param input file descriptor with the response from the solver + * \param Cache the solution should be applied on if any + * \param Progress is an instance to report progress to + * + * \return true if a solution is found and applied correctly, otherwise false + */ + bool static ReadResponse(int const input, pkgDepCache &Cache, OpProgress *Progress = NULL); + + /** \brief search and read the request stanza for action later + * + * This method while ignore the input up to the point it finds the + * Request: line as an indicator for the Request stanza. + * The request is stored in the parameters install and remove then, + * as the cache isn't build yet as the scenario follows the request. + * + * \param input file descriptor with the edsp input for the solver + * \param[out] install is a list which gets populated with requested installs + * \param[out] remove is a list which gets populated with requested removals + * \param[out] upgrade is true if it is a request like apt-get upgrade + * \param[out] distUpgrade is true if it is a request like apt-get dist-upgrade + * \param[out] autoRemove is true if removal of uneeded packages should be performed + * + * \return true if the request could be found and worked on, otherwise false + */ + bool static ReadRequest(int const input, std::list<std::string> &install, + std::list<std::string> &remove, bool &upgrade, + bool &distUpgrade, bool &autoRemove); + + /** \brief takes the request lists and applies it on the cache + * + * The lists as created by #ReadRequest will be used to find the + * packages in question and mark them for install/remove. + * No solving is done and no auto-install/-remove. + * + * \param install is a list of packages to mark for installation + * \param remove is a list of packages to mark for removal + * \param Cache is there the markers should be set + * + * \return false if the request couldn't be applied, true otherwise + */ + bool static ApplyRequest(std::list<std::string> const &install, + std::list<std::string> const &remove, + pkgDepCache &Cache); + + /** \brief encodes the changes in the Cache as a EDSP solution + * + * The markers in the Cache are observed and send to given + * file. The solution isn't checked for consistency or alike, + * so even broken solutions can be written successfully, + * but the front-end revicing it will properly fail then. + * + * \param Cache which represents the solution + * \param output to write the stanzas forming the solution to + * + * \return true if solution could be written, otherwise false + */ + bool static WriteSolution(pkgDepCache &Cache, FILE* output); + + /** \brief sends a progress report + * + * \param percent of the solving completed + * \param message the solver wants the user to see + * \param output the front-end listens for progress report + */ + bool static WriteProgress(unsigned short const percent, const char* const message, FILE* output); + + /** \brief sends an error report + * + * Solvers are expected to execute successfully even if + * 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. + * + * 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 output the front-end listens for error messages + */ + bool static WriteError(char const * const uuid, std::string const &message, FILE* output); + + + /** \brief executes the given solver and returns the pipe ends + * + * The given solver is executed if it can be found in one of the + * configured directories and setup for it is performed. + * + * \param solver to execute + * \param[out] solver_in will be the stdin of the solver + * \param[out] solver_out will be the stdout of the solver + * + * \return true if the solver could be started and the pipes + * are set up correctly, otherwise false and the pipes are invalid + */ + bool static ExecuteSolver(const char* const solver, int *solver_in, int *solver_out); + + /** \brief call an external resolver to handle the request + * + * This method wraps all the methods above to call an external solver + * + * \param solver to execute + * \param Cache with the problem and as universe to work in + * \param upgrade is true if it is a request like apt-get upgrade + * \param distUpgrade is true if it is a request like apt-get dist-upgrade + * \param autoRemove is true if unneeded packages should be removed + * \param Progress is an instance to report progress to + * + * \return true if the solver has successfully solved the problem, + * otherwise false + */ + bool static ResolveExternal(const char* const solver, pkgDepCache &Cache, + bool const upgrade, bool const distUpgrade, + bool const autoRemove, OpProgress *Progress = NULL); +}; + /*}}}*/ +#endif diff --git a/apt-pkg/edsp/edspindexfile.cc b/apt-pkg/edsp/edspindexfile.cc new file mode 100644 index 000000000..f5881e663 --- /dev/null +++ b/apt-pkg/edsp/edspindexfile.cc @@ -0,0 +1,78 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/* ###################################################################### + The scenario file is designed to work as an intermediate file between + APT and the resolver. Its on propose very similar to a dpkg status file + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include <apt-pkg/edspindexfile.h> +#include <apt-pkg/edsplistparser.h> +#include <apt-pkg/sourcelist.h> +#include <apt-pkg/configuration.h> +#include <apt-pkg/progress.h> +#include <apt-pkg/error.h> +#include <apt-pkg/strutl.h> +#include <apt-pkg/acquire-item.h> + +#include <sys/stat.h> + /*}}}*/ + +// edspIndex::edspIndex - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +edspIndex::edspIndex(string File) : debStatusIndex(File) +{ +} + /*}}}*/ +// StatusIndex::Merge - Load the index file into a cache /*{{{*/ +bool edspIndex::Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const +{ + FileFd Pkg; + if (File != "stdin") + Pkg.Open(File, FileFd::ReadOnly); + else + Pkg.OpenDescriptor(STDIN_FILENO, FileFd::ReadOnly); + if (_error->PendingError() == true) + return false; + edspListParser Parser(&Pkg); + if (_error->PendingError() == true) + return false; + + if (Prog != NULL) + Prog->SubProgress(0,File); + if (Gen.SelectFile(File,string(),*this) == false) + return _error->Error("Problem with SelectFile %s",File.c_str()); + + // Store the IMS information + pkgCache::PkgFileIterator CFile = Gen.GetCurFile(); + struct stat St; + if (fstat(Pkg.Fd(),&St) != 0) + return _error->Errno("fstat","Failed to stat"); + CFile->Size = St.st_size; + CFile->mtime = St.st_mtime; + CFile->Archive = Gen.WriteUniqString("edsp::scenario"); + + if (Gen.MergeList(Parser) == false) + return _error->Error("Problem with MergeList %s",File.c_str()); + return true; +} + /*}}}*/ +// Index File types for APT /*{{{*/ +class edspIFType: public pkgIndexFile::Type +{ + public: + virtual pkgRecords::Parser *CreatePkgParser(pkgCache::PkgFileIterator File) const + { + // we don't have a record parser for this type as the file is not presistent + return NULL; + }; + edspIFType() {Label = "EDSP scenario file";}; +}; +static edspIFType _apt_Universe; + +const pkgIndexFile::Type *edspIndex::GetType() const +{ + return &_apt_Universe; +} + /*}}}*/ diff --git a/apt-pkg/edsp/edspindexfile.h b/apt-pkg/edsp/edspindexfile.h new file mode 100644 index 000000000..0053388eb --- /dev/null +++ b/apt-pkg/edsp/edspindexfile.h @@ -0,0 +1,28 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/* ###################################################################### + The scenario file is designed to work as an intermediate file between + APT and the resolver. Its on propose very similar to a dpkg status file + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_EDSPINDEXFILE_H +#define PKGLIB_EDSPINDEXFILE_H + +#include <apt-pkg/indexfile.h> +#include <apt-pkg/debindexfile.h> + +class edspIndex : public debStatusIndex +{ + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; + + public: + + virtual const Type *GetType() const; + + virtual bool Merge(pkgCacheGenerator &Gen,OpProgress *Prog) const; + + edspIndex(string File); +}; + +#endif diff --git a/apt-pkg/edsp/edsplistparser.cc b/apt-pkg/edsp/edsplistparser.cc new file mode 100644 index 000000000..3349e8cce --- /dev/null +++ b/apt-pkg/edsp/edsplistparser.cc @@ -0,0 +1,90 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/* ###################################################################### + + Package Cache Generator - Generator for the cache structure. + + This builds the cache structure from the abstract package list parser. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include <apt-pkg/edsplistparser.h> +#include <apt-pkg/error.h> +#include <apt-pkg/configuration.h> +#include <apt-pkg/strutl.h> +#include <apt-pkg/md5.h> +#include <apt-pkg/macros.h> + /*}}}*/ + +// ListParser::edspListParser - Constructor /*{{{*/ +edspListParser::edspListParser(FileFd *File, string const &Arch) : debListParser(File, Arch) +{} + /*}}}*/ +// ListParser::NewVersion - Fill in the version structure /*{{{*/ +bool edspListParser::NewVersion(pkgCache::VerIterator &Ver) +{ + Ver->ID = Section.FindI("APT-ID", Ver->ID); + return debListParser::NewVersion(Ver); +} + /*}}}*/ +// ListParser::Description - Return the description string /*{{{*/ +// --------------------------------------------------------------------- +/* Sorry, no description for the resolvers… */ +string edspListParser::Description() +{ + return ""; +} +string edspListParser::DescriptionLanguage() +{ + return ""; +} +MD5SumValue edspListParser::Description_md5() +{ + return MD5SumValue(""); +} + /*}}}*/ +// ListParser::VersionHash - Compute a unique hash for this version /*{{{*/ +// --------------------------------------------------------------------- +/* */ +unsigned short edspListParser::VersionHash() +{ + if (Section.Exists("APT-Hash") == true) + return Section.FindI("APT-Hash"); + else if (Section.Exists("APT-ID") == true) + return Section.FindI("APT-ID"); + return 0; +} + /*}}}*/ +// ListParser::ParseStatus - Parse the status field /*{{{*/ +// --------------------------------------------------------------------- +/* The Status: line here is not a normal dpkg one but just one which tells + use if the package is installed or not, where missing means not. */ +bool edspListParser::ParseStatus(pkgCache::PkgIterator &Pkg, + pkgCache::VerIterator &Ver) +{ + unsigned long state = 0; + if (Section.FindFlag("Hold",state,pkgCache::State::Hold) == false) + return false; + if (state != 0) + Pkg->SelectedState = pkgCache::State::Hold; + + state = 0; + if (Section.FindFlag("Installed",state,pkgCache::State::Installed) == false) + return false; + if (state != 0) + { + Pkg->CurrentState = pkgCache::State::Installed; + Pkg->CurrentVer = Ver.Index(); + } + + return true; +} + /*}}}*/ +// ListParser::LoadReleaseInfo - Load the release information /*{{{*/ +bool edspListParser::LoadReleaseInfo(pkgCache::PkgFileIterator &FileI, + FileFd &File, string component) +{ + return true; +} + /*}}}*/ diff --git a/apt-pkg/edsp/edsplistparser.h b/apt-pkg/edsp/edsplistparser.h new file mode 100644 index 000000000..ec9f09905 --- /dev/null +++ b/apt-pkg/edsp/edsplistparser.h @@ -0,0 +1,38 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/* ###################################################################### + + EDSP Package List Parser - This implements the abstract parser + interface for the APT specific intermediate format which is passed + to external resolvers + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_EDSPLISTPARSER_H +#define PKGLIB_EDSPLISTPARSER_H + +#include <apt-pkg/deblistparser.h> +#include <apt-pkg/pkgcachegen.h> +#include <apt-pkg/indexfile.h> +#include <apt-pkg/tagfile.h> + +class edspListParser : public debListParser +{ + public: + virtual bool NewVersion(pkgCache::VerIterator &Ver); + virtual string Description(); + virtual string DescriptionLanguage(); + virtual MD5SumValue Description_md5(); + virtual unsigned short VersionHash(); + + bool LoadReleaseInfo(pkgCache::PkgFileIterator &FileI,FileFd &File, + string section); + + edspListParser(FileFd *File, string const &Arch = ""); + + protected: + virtual bool ParseStatus(pkgCache::PkgIterator &Pkg,pkgCache::VerIterator &Ver); + +}; + +#endif diff --git a/apt-pkg/edsp/edspsystem.cc b/apt-pkg/edsp/edspsystem.cc new file mode 100644 index 000000000..ac0bb8beb --- /dev/null +++ b/apt-pkg/edsp/edspsystem.cc @@ -0,0 +1,124 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/* ###################################################################### + + This system provides the abstraction to use the scenario file as the + only source of package information to be able to feed the created file + back to APT for its own consumption (eat your own dogfood). + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include <apt-pkg/edspsystem.h> +#include <apt-pkg/debversion.h> +#include <apt-pkg/edspindexfile.h> +#include <apt-pkg/configuration.h> +#include <apt-pkg/error.h> +#include <apt-pkg/fileutl.h> +#include <apti18n.h> +#include <sys/types.h> +#include <unistd.h> +#include <dirent.h> +#include <errno.h> + /*}}}*/ + +edspSystem edspSys; + +// System::debSystem - Constructor /*{{{*/ +edspSystem::edspSystem() +{ + StatusFile = 0; + + Label = "Debian APT solver interface"; + VS = &debVS; +} + /*}}}*/ +// System::~debSystem - Destructor /*{{{*/ +edspSystem::~edspSystem() +{ + delete StatusFile; +} + /*}}}*/ +// System::Lock - Get the lock /*{{{*/ +bool edspSystem::Lock() +{ + return true; +} + /*}}}*/ +// System::UnLock - Drop a lock /*{{{*/ +bool edspSystem::UnLock(bool NoErrors) +{ + return true; +} + /*}}}*/ +// System::CreatePM - Create the underlying package manager /*{{{*/ +// --------------------------------------------------------------------- +/* we can't use edsp input as input for real installations - just a + simulation can work, but everything else will fail bigtime */ +pkgPackageManager *edspSystem::CreatePM(pkgDepCache *Cache) const +{ + return NULL; +} + /*}}}*/ +// System::Initialize - Setup the configuration space.. /*{{{*/ +bool edspSystem::Initialize(Configuration &Cnf) +{ + Cnf.Set("Dir::State::extended_states", "/dev/null"); + Cnf.Set("Dir::State::status","/dev/null"); + Cnf.Set("Dir::State::lists","/dev/null"); + + Cnf.Set("Debug::NoLocking", "true"); + Cnf.Set("APT::Get::Simulate", "true"); + + if (StatusFile) { + delete StatusFile; + StatusFile = 0; + } + return true; +} + /*}}}*/ +// System::ArchiveSupported - Is a file format supported /*{{{*/ +bool edspSystem::ArchiveSupported(const char *Type) +{ + return false; +} + /*}}}*/ +// System::Score - Determine if we should use the edsp system /*{{{*/ +signed edspSystem::Score(Configuration const &Cnf) +{ + if (Cnf.Find("edsp::scenario", "") == "stdin") + return 1000; + if (FileExists(Cnf.FindFile("edsp::scenario","")) == true) + return 1000; + return -1000; +} + /*}}}*/ +// System::AddStatusFiles - Register the status files /*{{{*/ +bool edspSystem::AddStatusFiles(vector<pkgIndexFile *> &List) +{ + if (StatusFile == 0) + { + if (_config->Find("edsp::scenario", "") == "stdin") + StatusFile = new edspIndex("stdin"); + else + StatusFile = new edspIndex(_config->FindFile("edsp::scenario")); + } + List.push_back(StatusFile); + return true; +} + /*}}}*/ +// System::FindIndex - Get an index file for status files /*{{{*/ +bool edspSystem::FindIndex(pkgCache::PkgFileIterator File, + pkgIndexFile *&Found) const +{ + if (StatusFile == 0) + return false; + if (StatusFile->FindInCache(*File.Cache()) == File) + { + Found = StatusFile; + return true; + } + + return false; +} + /*}}}*/ diff --git a/apt-pkg/edsp/edspsystem.h b/apt-pkg/edsp/edspsystem.h new file mode 100644 index 000000000..ca703fa84 --- /dev/null +++ b/apt-pkg/edsp/edspsystem.h @@ -0,0 +1,41 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: debsystem.h,v 1.4 2003/01/11 07:16:33 jgg Exp $ +/* ###################################################################### + + System - Debian version of the System Class + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_EDSPSYSTEM_H +#define PKGLIB_EDSPSYSTEM_H + +#include <apt-pkg/pkgsystem.h> + +class edspIndex; +class edspSystem : public pkgSystem +{ + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; + + edspIndex *StatusFile; + + public: + + virtual bool Lock(); + virtual bool UnLock(bool NoErrors = false); + virtual pkgPackageManager *CreatePM(pkgDepCache *Cache) const; + virtual bool Initialize(Configuration &Cnf); + virtual bool ArchiveSupported(const char *Type); + virtual signed Score(Configuration const &Cnf); + virtual bool AddStatusFiles(std::vector<pkgIndexFile *> &List); + virtual bool FindIndex(pkgCache::PkgFileIterator File, + pkgIndexFile *&Found) const; + + edspSystem(); + ~edspSystem(); +}; + +extern edspSystem edspSys; + +#endif diff --git a/apt-pkg/indexcopy.h b/apt-pkg/indexcopy.h index 6fcd3b8ce..277fb561c 100644 --- a/apt-pkg/indexcopy.h +++ b/apt-pkg/indexcopy.h @@ -24,6 +24,9 @@ class pkgCdromStatus; class IndexCopy /*{{{*/ { + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; + protected: pkgTagSection *Section; @@ -55,7 +58,6 @@ class PackageCopy : public IndexCopy /*{{{*/ virtual const char *GetFileName() {return "Packages";}; virtual const char *Type() {return "Package";}; - public: }; /*}}}*/ class SourceCopy : public IndexCopy /*{{{*/ @@ -67,7 +69,6 @@ class SourceCopy : public IndexCopy /*{{{*/ virtual const char *GetFileName() {return "Sources";}; virtual const char *Type() {return "Source";}; - public: }; /*}}}*/ class TranslationsCopy /*{{{*/ @@ -82,6 +83,9 @@ class TranslationsCopy /*{{{*/ /*}}}*/ class SigVerify /*{{{*/ { + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; + bool Verify(string prefix,string file, indexRecords *records); bool CopyMetaIndex(string CDROM, string CDName, string prefix, string file); diff --git a/apt-pkg/init.cc b/apt-pkg/init.cc index 38a0814e5..4f3101687 100644 --- a/apt-pkg/init.cc +++ b/apt-pkg/init.cc @@ -74,6 +74,7 @@ bool pkgInitConfig(Configuration &Cnf) Cnf.CndSet("Dir::Etc::trusted", "trusted.gpg"); Cnf.CndSet("Dir::Etc::trustedparts","trusted.gpg.d"); Cnf.CndSet("Dir::Bin::methods","/usr/lib/apt/methods"); + Cnf.CndSet("Dir::Bin::solvers::","/usr/lib/apt/solvers"); Cnf.CndSet("Dir::Media::MountPath","/media/apt"); // State @@ -87,6 +88,9 @@ bool pkgInitConfig(Configuration &Cnf) Cnf.Set("Dir::Ignore-Files-Silently::", "\\.disabled$"); Cnf.Set("Dir::Ignore-Files-Silently::", "\\.bak$"); Cnf.Set("Dir::Ignore-Files-Silently::", "\\.dpkg-[a-z]+$"); + // ubuntu specific + Cnf.Set("Dir::Ignore-Files-Silently::", "\\.distUpgrade$"); + Cnf.Set("Dir::Ignore-Files-Silently::", "\\.save$"); } // Default cdrom mount point diff --git a/apt-pkg/init.h b/apt-pkg/init.h index 15a1165b9..6b92dd200 100644 --- a/apt-pkg/init.h +++ b/apt-pkg/init.h @@ -22,8 +22,8 @@ // Non-ABI-Breaks should only increase RELEASE number. // See also buildlib/libversion.mak #define APT_PKG_MAJOR 4 -#define APT_PKG_MINOR 10 -#define APT_PKG_RELEASE 1 +#define APT_PKG_MINOR 11 +#define APT_PKG_RELEASE 0 extern const char *pkgVersion; extern const char *pkgLibVersion; diff --git a/apt-pkg/makefile b/apt-pkg/makefile index 4e5ec107f..e1f69dd65 100644 --- a/apt-pkg/makefile +++ b/apt-pkg/makefile @@ -3,7 +3,7 @@ BASE=.. SUBDIR=apt-pkg # Header location -SUBDIRS = deb contrib +SUBDIRS = deb edsp contrib HEADER_TARGETDIRS = apt-pkg # Bring in the default rules @@ -20,11 +20,15 @@ APT_DOMAIN:=libapt-pkg$(LIBAPTPKG_MAJOR) # Source code for the contributed non-core things SOURCE = contrib/mmap.cc contrib/error.cc contrib/strutl.cc \ contrib/configuration.cc contrib/progress.cc contrib/cmndline.cc \ - contrib/md5.cc contrib/sha1.cc contrib/sha256.cc contrib/hashes.cc \ + contrib/hashsum.cc contrib/md5.cc contrib/sha1.cc \ + contrib/sha2_internal.cc\ + contrib/hashes.cc \ contrib/cdromutl.cc contrib/crc-16.cc contrib/netrc.cc \ contrib/fileutl.cc HEADERS = mmap.h error.h configuration.h fileutl.h cmndline.h netrc.h\ - md5.h crc-16.h cdromutl.h strutl.h sptr.h sha1.h sha256.h hashes.h \ + md5.h crc-16.h cdromutl.h strutl.h sptr.h sha1.h sha2.h sha256.h\ + sha2_internal.h \ + hashes.h hashsum_template.h\ macros.h weakptr.h # Source code for the core main library @@ -35,7 +39,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 + 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 \ @@ -43,7 +47,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 + cachefilter.h cacheset.h edsp.h # Source code for the debian specific components # In theory the deb headers do not need to be exported.. @@ -53,6 +57,10 @@ SOURCE+= deb/deblistparser.cc deb/debrecords.cc deb/dpkgpm.cc \ HEADERS+= debversion.h debsrcrecords.h dpkgpm.h debrecords.h \ deblistparser.h debsystem.h debindexfile.h debmetaindex.h +# Source code for the APT resolver interface specific components +SOURCE+= edsp/edsplistparser.cc edsp/edspindexfile.cc edsp/edspsystem.cc +HEADERS+= edsplistparser.h edspindexfile.h edspsystem.h + HEADERS := $(addprefix apt-pkg/,$(HEADERS)) include $(LIBRARY_H) diff --git a/apt-pkg/metaindex.h b/apt-pkg/metaindex.h index 1d2140799..f60235a5d 100644 --- a/apt-pkg/metaindex.h +++ b/apt-pkg/metaindex.h @@ -39,6 +39,10 @@ class metaIndex virtual vector<pkgIndexFile *> *GetIndexFiles() = 0; virtual bool IsTrusted() const = 0; + metaIndex(string const &URI, string const &Dist, char const * const Type) : + Indexes(NULL), Type(Type), URI(URI), Dist(Dist) { + } + virtual ~metaIndex() { if (Indexes == 0) return; diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index 060cd3248..a3ba26f7c 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -319,7 +319,7 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg) List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); } - if (Cache[Pkg].InstVerIter(Cache)->MultiArch == pkgCache::Version::Same) + if ((Cache[Pkg].InstVerIter(Cache)->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same) for (PkgIterator P = Pkg.Group().PackageList(); P.end() == false; P = Pkg.Group().NextPkg(P)) { @@ -602,7 +602,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate) List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States); - if (instVer->MultiArch == pkgCache::Version::Same) + if ((instVer->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same) for (PkgIterator P = Pkg.Group().PackageList(); P.end() == false; P = Pkg.Group().NextPkg(P)) { diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index ed24d9ea8..faccafbef 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -84,6 +84,8 @@ pkgCache::Header::Header() memset(PkgHashTable,0,sizeof(PkgHashTable)); memset(GrpHashTable,0,sizeof(GrpHashTable)); memset(Pools,0,sizeof(Pools)); + + CacheFileSize = 0; } /*}}}*/ // Cache::Header::CheckSizes - Check if the two headers have same *sz /*{{{*/ @@ -155,6 +157,9 @@ bool pkgCache::ReMap(bool const &Errorchecks) HeaderP->CheckSizes(DefHeader) == false) return _error->Error(_("The package cache file is an incompatible version")); + if (Map.Size() < HeaderP->CacheFileSize) + return _error->Error(_("The package cache file is corrupted, it is too small")); + // Locate our VS.. if (HeaderP->VerSysName == 0 || (VS = pkgVersioningSystem::GetVS(StrP + HeaderP->VerSysName)) == 0) @@ -749,9 +754,6 @@ bool pkgCache::VerIterator::Automatic() const return false; } /*}}}*/ -// VerIterator::Pseudo - deprecated no-op method /*{{{*/ -bool pkgCache::VerIterator::Pseudo() const { return false; } - /*}}}*/ // VerIterator::NewestFile - Return the newest file version relation /*{{{*/ // --------------------------------------------------------------------- /* This looks at the version numbers associated with all of the sources diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h index 1b1743724..87912aead 100644 --- a/apt-pkg/pkgcache.h +++ b/apt-pkg/pkgcache.h @@ -314,6 +314,9 @@ struct pkgCache::Header map_ptrloc PkgHashTable[2*1048]; map_ptrloc GrpHashTable[2*1048]; + /** \brief Size of the complete cache file */ + unsigned long CacheFileSize; + bool CheckSizes(Header &Against) const; Header(); }; @@ -500,15 +503,20 @@ struct pkgCache::Version map_ptrloc VerStr; // StringItem /** \brief section this version is filled in */ map_ptrloc Section; // StringItem + + /** \brief Multi-Arch capabilities of a package version */ + enum VerMultiArch { None = 0, /*!< is the default and doesn't trigger special behaviour */ + All = (1<<0), /*!< will cause that Ver.Arch() will report "all" */ + Foreign = (1<<1), /*!< can satisfy dependencies in another architecture */ + Same = (1<<2), /*!< can be co-installed with itself from other architectures */ + Allowed = (1<<3), /*!< other packages are allowed to depend on thispkg:any */ + AllForeign = All | Foreign, + AllAllowed = All | Allowed }; /** \brief stores the MultiArch capabilities of this version - None is the default and doesn't trigger special behaviour, - Foreign means that this version can fulfill dependencies even - if it is built for another architecture as the requester. - Same indicates that builds for different architectures can - be co-installed on the system */ - /* FIXME: A bitflag would be better with the next abibreak… */ - enum {None, All, Foreign, Same, Allowed, AllForeign, AllAllowed} MultiArch; + Flags used are defined in pkgCache::Version::VerMultiArch + */ + unsigned char MultiArch; /** \brief references all the PackageFile's that this version came from diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index dc5a830bd..f41bb5a0a 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -98,6 +98,7 @@ pkgCacheGenerator::~pkgCacheGenerator() return; Cache.HeaderP->Dirty = false; + Cache.HeaderP->CacheFileSize = Map.Size(); Map.Sync(0,sizeof(pkgCache::Header)); } /*}}}*/ diff --git a/apt-pkg/pkgrecords.h b/apt-pkg/pkgrecords.h index c2c98188a..ce92cacc4 100644 --- a/apt-pkg/pkgrecords.h +++ b/apt-pkg/pkgrecords.h @@ -28,12 +28,13 @@ class pkgRecords /*{{{*/ class Parser; private: + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; pkgCache &Cache; std::vector<Parser *>Files; - public: - + public: // Lookup function Parser &Lookup(pkgCache::VerFileIterator const &Ver); Parser &Lookup(pkgCache::DescFileIterator const &Desc); @@ -58,6 +59,7 @@ class pkgRecords::Parser /*{{{*/ virtual string MD5Hash() {return string();}; virtual string SHA1Hash() {return string();}; virtual string SHA256Hash() {return string();}; + virtual string SHA512Hash() {return string();}; virtual string SourcePkg() {return string();}; virtual string SourceVer() {return string();}; @@ -67,7 +69,10 @@ class pkgRecords::Parser /*{{{*/ virtual string LongDesc() {return string();}; virtual string Name() {return string();}; virtual string Homepage() {return string();} - + + // An arbitrary custom field + virtual string RecordField(const char *fieldName) { return string();}; + // The record in binary form virtual void GetRec(const char *&Start,const char *&Stop) {Start = Stop = 0;}; diff --git a/apt-pkg/policy.cc b/apt-pkg/policy.cc index 6a5130d48..0cc77e0af 100644 --- a/apt-pkg/policy.cc +++ b/apt-pkg/policy.cc @@ -320,6 +320,10 @@ signed short pkgPolicy::GetPriority(pkgCache::PkgIterator const &Pkg) return 0; } +signed short pkgPolicy::GetPriority(pkgCache::PkgFileIterator const &File) +{ + return PFPriority[File->ID]; +} /*}}}*/ // PreferenceSection class - Overriding the default TrimRecord method /*{{{*/ // --------------------------------------------------------------------- diff --git a/apt-pkg/policy.h b/apt-pkg/policy.h index a5e6c6048..92d32728f 100644 --- a/apt-pkg/policy.h +++ b/apt-pkg/policy.h @@ -70,14 +70,13 @@ class pkgPolicy : public pkgDepCache::Policy // Things for manipulating pins void CreatePin(pkgVersionMatch::MatchType Type,string Pkg, string Data,signed short Priority); - inline signed short GetPriority(pkgCache::PkgFileIterator const &File) - {return PFPriority[File->ID];}; - signed short GetPriority(pkgCache::PkgIterator const &Pkg); pkgCache::VerIterator GetMatch(pkgCache::PkgIterator const &Pkg); // Things for the cache interface. virtual pkgCache::VerIterator GetCandidateVer(pkgCache::PkgIterator const &Pkg); - virtual bool IsImportantDep(pkgCache::DepIterator const &Dep) {return pkgDepCache::Policy::IsImportantDep(Dep);}; + virtual signed short GetPriority(pkgCache::PkgIterator const &Pkg); + virtual signed short GetPriority(pkgCache::PkgFileIterator const &File); + bool InitDefaults(); pkgPolicy(pkgCache *Owner); diff --git a/apt-pkg/sourcelist.cc b/apt-pkg/sourcelist.cc index a25358bf2..47800b0c2 100644 --- a/apt-pkg/sourcelist.cc +++ b/apt-pkg/sourcelist.cc @@ -346,10 +346,14 @@ bool pkgSourceList::ReadSourceDir(string Dir) /* */ time_t pkgSourceList::GetLastModifiedTime() { - // go over the parts + vector<string> List; + string Main = _config->FindFile("Dir::Etc::sourcelist"); string Parts = _config->FindDir("Dir::Etc::sourceparts"); - vector<string> const List = GetListOfFilesInDir(Parts, "list", true); + + // go over the parts + if (DirectoryExists(Parts) == true) + List = GetListOfFilesInDir(Parts, "list", true); // calculate the time time_t mtime_sources = GetModificationTime(Main); diff --git a/apt-pkg/srcrecords.h b/apt-pkg/srcrecords.h index a49533864..8a78d7711 100644 --- a/apt-pkg/srcrecords.h +++ b/apt-pkg/srcrecords.h @@ -79,6 +79,8 @@ class pkgSrcRecords }; private: + /** \brief dpointer placeholder (for later in case we need it) */ + void *d; // The list of files and the current parser pointer vector<Parser*> Files; @@ -93,7 +95,7 @@ class pkgSrcRecords Parser *Find(const char *Package,bool const &SrcOnly = false); pkgSrcRecords(pkgSourceList &List); - ~pkgSrcRecords(); + virtual ~pkgSrcRecords(); }; #endif diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc index 4a2f3f7e6..a8f04b23a 100644 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@ -24,26 +24,40 @@ using std::string; +class pkgTagFilePrivate +{ +public: + pkgTagFilePrivate(FileFd *pFd, unsigned long Size) : Fd(*pFd), Size(Size) + { + } + FileFd &Fd; + char *Buffer; + char *Start; + char *End; + bool Done; + unsigned long iOffset; + unsigned long Size; +}; + // TagFile::pkgTagFile - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -pkgTagFile::pkgTagFile(FileFd *pFd,unsigned long Size) : - Fd(*pFd), - Size(Size) +pkgTagFile::pkgTagFile(FileFd *pFd,unsigned long Size) { - if (Fd.IsOpen() == false) + d = new pkgTagFilePrivate(pFd, Size); + + if (d->Fd.IsOpen() == false) { - Buffer = 0; - Start = End = Buffer = 0; - Done = true; - iOffset = 0; + d->Start = d->End = d->Buffer = 0; + d->Done = true; + d->iOffset = 0; return; } - Buffer = new char[Size]; - Start = End = Buffer; - Done = false; - iOffset = 0; + d->Buffer = new char[Size]; + d->Start = d->End = d->Buffer; + d->Done = false; + d->iOffset = 0; Fill(); } /*}}}*/ @@ -52,7 +66,14 @@ pkgTagFile::pkgTagFile(FileFd *pFd,unsigned long Size) : /* */ pkgTagFile::~pkgTagFile() { - delete [] Buffer; + delete [] d->Buffer; + delete d; +} + /*}}}*/ +// TagFile::Offset - Return the current offset in the buffer /*{{{*/ +unsigned long pkgTagFile::Offset() +{ + return d->iOffset; } /*}}}*/ // TagFile::Resize - Resize the internal buffer /*{{{*/ @@ -63,22 +84,22 @@ pkgTagFile::~pkgTagFile() bool pkgTagFile::Resize() { char *tmp; - unsigned long EndSize = End - Start; + unsigned long EndSize = d->End - d->Start; // fail is the buffer grows too big - if(Size > 1024*1024+1) + if(d->Size > 1024*1024+1) return false; // get new buffer and use it - tmp = new char[2*Size]; - memcpy(tmp, Buffer, Size); - Size = Size*2; - delete [] Buffer; - Buffer = tmp; + tmp = new char[2*d->Size]; + memcpy(tmp, d->Buffer, d->Size); + d->Size = d->Size*2; + delete [] d->Buffer; + d->Buffer = tmp; // update the start/end pointers to the new buffer - Start = Buffer; - End = Start + EndSize; + d->Start = d->Buffer; + d->End = d->Start + EndSize; return true; } /*}}}*/ @@ -90,20 +111,20 @@ bool pkgTagFile::Resize() */ bool pkgTagFile::Step(pkgTagSection &Tag) { - while (Tag.Scan(Start,End - Start) == false) + while (Tag.Scan(d->Start,d->End - d->Start) == false) { if (Fill() == false) return false; - if(Tag.Scan(Start,End - Start)) + if(Tag.Scan(d->Start,d->End - d->Start)) break; if (Resize() == false) return _error->Error(_("Unable to parse package file %s (1)"), - Fd.Name().c_str()); + d->Fd.Name().c_str()); } - Start += Tag.size(); - iOffset += Tag.size(); + d->Start += Tag.size(); + d->iOffset += Tag.size(); Tag.Trim(); return true; @@ -115,37 +136,37 @@ bool pkgTagFile::Step(pkgTagSection &Tag) then fills the rest from the file */ bool pkgTagFile::Fill() { - unsigned long EndSize = End - Start; + unsigned long EndSize = d->End - d->Start; unsigned long Actual = 0; - memmove(Buffer,Start,EndSize); - Start = Buffer; - End = Buffer + EndSize; + memmove(d->Buffer,d->Start,EndSize); + d->Start = d->Buffer; + d->End = d->Buffer + EndSize; - if (Done == false) + if (d->Done == false) { // See if only a bit of the file is left - if (Fd.Read(End,Size - (End - Buffer),&Actual) == false) + if (d->Fd.Read(d->End, d->Size - (d->End - d->Buffer),&Actual) == false) return false; - if (Actual != Size - (End - Buffer)) - Done = true; - End += Actual; + if (Actual != d->Size - (d->End - d->Buffer)) + d->Done = true; + d->End += Actual; } - if (Done == true) + if (d->Done == true) { if (EndSize <= 3 && Actual == 0) return false; - if (Size - (End - Buffer) < 4) + if (d->Size - (d->End - d->Buffer) < 4) return true; // Append a double new line if one does not exist unsigned int LineCount = 0; - for (const char *E = End - 1; E - End < 6 && (*E == '\n' || *E == '\r'); E--) + for (const char *E = d->End - 1; E - d->End < 6 && (*E == '\n' || *E == '\r'); E--) if (*E == '\n') LineCount++; for (; LineCount < 2; LineCount++) - *End++ = '\n'; + *d->End++ = '\n'; return true; } @@ -160,33 +181,33 @@ bool pkgTagFile::Fill() bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long Offset) { // We are within a buffer space of the next hit.. - if (Offset >= iOffset && iOffset + (End - Start) > Offset) + if (Offset >= d->iOffset && d->iOffset + (d->End - d->Start) > Offset) { - unsigned long Dist = Offset - iOffset; - Start += Dist; - iOffset += Dist; + unsigned long Dist = Offset - d->iOffset; + d->Start += Dist; + d->iOffset += Dist; return Step(Tag); } // Reposition and reload.. - iOffset = Offset; - Done = false; - if (Fd.Seek(Offset) == false) + d->iOffset = Offset; + d->Done = false; + if (d->Fd.Seek(Offset) == false) return false; - End = Start = Buffer; + d->End = d->Start = d->Buffer; if (Fill() == false) return false; - if (Tag.Scan(Start,End - Start) == true) + if (Tag.Scan(d->Start, d->End - d->Start) == true) return true; // This appends a double new line (for the real eof handling) if (Fill() == false) return false; - if (Tag.Scan(Start,End - Start) == false) - return _error->Error(_("Unable to parse package file %s (2)"),Fd.Name().c_str()); + if (Tag.Scan(d->Start, d->End - d->Start) == false) + return _error->Error(_("Unable to parse package file %s (2)"),d->Fd.Name().c_str()); return true; } @@ -457,6 +478,7 @@ static const char *iTFRewritePackageOrder[] = { "MD5Sum", "SHA1", "SHA256", + "SHA512", "MSDOS-Filename", // Obsolete "Description", 0}; diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h index a101d7b1e..3a2dee7c7 100644 --- a/apt-pkg/tagfile.h +++ b/apt-pkg/tagfile.h @@ -23,16 +23,16 @@ #include <apt-pkg/fileutl.h> #include <stdio.h> - + class pkgTagSection { const char *Section; - // We have a limit of 256 tags per section. unsigned int Indexes[256]; unsigned int AlphaIndexes[0x100]; - unsigned int TagCount; + // dpointer placeholder (for later in case we need it) + void *d; /* This very simple hash function for the last 8 letters gives very good performance on the debian package files */ @@ -44,7 +44,6 @@ class pkgTagSection return Res & 0xFF; } - protected: const char *Stop; @@ -80,17 +79,13 @@ class pkgTagSection }; pkgTagSection() : Section(0), TagCount(0), Stop(0) {}; + virtual ~pkgTagSection() {}; }; +class pkgTagFilePrivate; class pkgTagFile { - FileFd &Fd; - char *Buffer; - char *Start; - char *End; - bool Done; - unsigned long iOffset; - unsigned long Size; + pkgTagFilePrivate *d; bool Fill(); bool Resize(); @@ -98,11 +93,11 @@ class pkgTagFile public: bool Step(pkgTagSection &Section); - inline unsigned long Offset() {return iOffset;}; + unsigned long Offset(); bool Jump(pkgTagSection &Tag,unsigned long Offset); pkgTagFile(FileFd *F,unsigned long Size = 32*1024); - ~pkgTagFile(); + virtual ~pkgTagFile(); }; /* This is the list of things to rewrite. The rewriter |