15
15
// Include Files /*{{{*/
16
16
#include <apt-pkg/acquire-item.h>
17
#include <apt-pkg/contrib/configuration.h>
17
#include <apt-pkg/configuration.h>
18
#include <apt-pkg/aptconfiguration.h>
18
19
#include <apt-pkg/sourcelist.h>
19
20
#include <apt-pkg/vendorlist.h>
20
#include <apt-pkg/contrib/error.h>
21
#include <apt-pkg/contrib/strutl.h>
22
#include <apt-pkg/contrib/fileutl.h>
23
#include <apt-pkg/contrib/md5.h>
24
#include <apt-pkg/contrib/sha1.h>
21
#include <apt-pkg/error.h>
22
#include <apt-pkg/strutl.h>
23
#include <apt-pkg/fileutl.h>
24
#include <apt-pkg/md5.h>
25
#include <apt-pkg/sha1.h>
25
26
#include <apt-pkg/tagfile.h>
27
28
#include <apti18n.h>
137
// AcqDiffIndex::AcqDiffIndex - Constructor
135
// AcqDiffIndex::AcqDiffIndex - Constructor /*{{{*/
138
136
// ---------------------------------------------------------------------
139
137
/* Get the DiffIndex file first and see if there are patches availabe
140
138
* If so, create a pkgAcqIndexDiffs fetcher that will get and apply the
204
202
return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
208
bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile)
205
bool pkgAcqDiffIndex::ParseDiffIndex(string IndexDiffFile) /*{{{*/
211
208
std::clog << "pkgAcqIndexDiffs::ParseIndexDiff() " << IndexDiffFile
223
220
if(TF.Step(Tags) == true)
226
222
bool found = false;
230
string tmp = Tags.FindS("SHA1-Current");
226
string const tmp = Tags.FindS("SHA1-Current");
231
227
std::stringstream ss(tmp);
228
ss >> ServerSha1 >> size;
229
unsigned long const ServerSize = atol(size.c_str());
234
231
FileFd fd(CurrentPackagesFile, FileFd::ReadOnly);
235
232
SHA1Summation SHA1;
236
233
SHA1.AddFD(fd.Fd(), fd.Size());
237
local_sha1 = string(SHA1.Result());
234
string const local_sha1 = SHA1.Result();
239
236
if(local_sha1 == ServerSha1)
251
248
std::clog << "SHA1-Current: " << ServerSha1 << std::endl;
253
250
// check the historie and see what patches we need
254
string history = Tags.FindS("SHA1-History");
251
string const history = Tags.FindS("SHA1-History");
255
252
std::stringstream hist(history);
256
while(hist >> d.sha1 >> size >> d.file)
253
while(hist >> d.sha1 >> size >> d.file)
258
d.size = atoi(size.c_str());
259
255
// read until the first match is found
256
// from that point on, we probably need all diffs
260
257
if(d.sha1 == local_sha1)
262
// from that point on, we probably need all diffs
266
std::clog << "Need to get diff: " << d.file << std::endl;
267
available_patches.push_back(d);
259
else if (found == false)
263
std::clog << "Need to get diff: " << d.file << std::endl;
264
available_patches.push_back(d);
267
if (available_patches.empty() == false)
269
// patching with too many files is rather slow compared to a fast download
270
unsigned long const fileLimit = _config->FindI("Acquire::PDiffs::FileLimit", 0);
271
if (fileLimit != 0 && fileLimit < available_patches.size())
274
std::clog << "Need " << available_patches.size() << " diffs (Limit is " << fileLimit
275
<< ") so fallback to complete download" << std::endl;
279
// see if the patches are too big
280
found = false; // it was true and it will be true again at the end
281
d = *available_patches.begin();
282
string const firstPatch = d.file;
283
unsigned long patchesSize = 0;
284
std::stringstream patches(Tags.FindS("SHA1-Patches"));
285
while(patches >> d.sha1 >> size >> d.file)
287
if (firstPatch == d.file)
289
else if (found == false)
292
patchesSize += atol(size.c_str());
294
unsigned long const sizeLimit = ServerSize * _config->FindI("Acquire::PDiffs::SizeLimit", 100);
295
if (sizeLimit > 0 && (sizeLimit/100) < patchesSize)
298
std::clog << "Need " << patchesSize << " bytes (Limit is " << sizeLimit/100
299
<< ") so fallback to complete download" << std::endl;
275
308
// queue the diffs
276
string::size_type last_space = Description.rfind(" ");
309
string::size_type const last_space = Description.rfind(" ");
277
310
if(last_space != string::npos)
278
311
Description.erase(last_space, Description.size()-last_space);
279
312
new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc,
280
ExpectedHash, available_patches);
313
ExpectedHash, ServerSha1, available_patches);
281
314
Complete = false;
282
315
Status = StatDone;
292
325
std::clog << "Can't find a patch in the index file" << std::endl;
296
void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
329
void pkgAcqDiffIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/
299
332
std::clog << "pkgAcqDiffIndex failed: " << Desc.URI << std::endl
306
339
Status = StatDone;
310
void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash,
343
void pkgAcqDiffIndex::Done(string Message,unsigned long Size,string Md5Hash, /*{{{*/
311
344
pkgAcquire::MethodConfig *Cnf)
342
// AcqIndexDiffs::AcqIndexDiffs - Constructor
373
// AcqIndexDiffs::AcqIndexDiffs - Constructor /*{{{*/
343
374
// ---------------------------------------------------------------------
344
375
/* The package diff is added to the queue. one object is constructed
345
376
* for each diff and the index
347
378
pkgAcqIndexDiffs::pkgAcqIndexDiffs(pkgAcquire *Owner,
348
379
string URI,string URIDesc,string ShortDesc,
349
380
HashString ExpectedHash,
350
382
vector<DiffInfo> diffs)
351
383
: Item(Owner), RealURI(URI), ExpectedHash(ExpectedHash),
352
available_patches(diffs)
384
available_patches(diffs), ServerSha1(ServerSha1)
355
387
DestFile = _config->FindDir("Dir::State::lists") + "partial/";
378
void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
409
void pkgAcqIndexDiffs::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/
381
412
std::clog << "pkgAcqIndexDiffs failed: " << Desc.URI << std::endl
389
// helper that cleans the item out of the fetcher queue
419
// Finish - helper that cleans the item out of the fetcher queue /*{{{*/
390
420
void pkgAcqIndexDiffs::Finish(bool allDone)
392
422
// we restore the original name, this is required, otherwise
439
467
std::clog << "QueueNextDiff: "
440
468
<< FinalFile << " (" << local_sha1 << ")"<<std::endl;
470
// final file reached before all patches are applied
471
if(local_sha1 == ServerSha1)
442
477
// remove all patches until the next matching patch is found
443
478
// this requires the Index file to be ordered
444
479
for(vector<DiffInfo>::iterator I=available_patches.begin();
476
void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash,
509
void pkgAcqIndexDiffs::Done(string Message,unsigned long Size,string Md5Hash, /*{{{*/
477
510
pkgAcquire::MethodConfig *Cnf)
538
571
// see if there is more to download
539
572
if(available_patches.size() > 0) {
540
573
new pkgAcqIndexDiffs(Owner, RealURI, Description, Desc.ShortDesc,
541
ExpectedHash, available_patches);
574
ExpectedHash, ServerSha1, available_patches);
544
577
return Finish(true);
549
581
// AcqIndex::AcqIndex - Constructor /*{{{*/
550
582
// ---------------------------------------------------------------------
551
583
/* The package file is added to the queue and a second class is
564
596
if(comprExt.empty())
566
598
// autoselect the compression method
567
if(FileExists("/bin/bzip2"))
568
CompressionExtension = ".bz2";
570
CompressionExtension = ".gz";
572
CompressionExtension = (comprExt == "plain" ? "" : comprExt);
599
std::vector<std::string> types = APT::Configuration::getCompressionTypes();
600
if (types.empty() == true)
603
comprExt = "." + types[0];
605
CompressionExtension = ((comprExt == "plain" || comprExt == ".") ? "" : comprExt);
574
607
Desc.URI = URI + CompressionExtension;
576
609
Desc.Description = URIDesc;
595
628
return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
599
void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
631
void pkgAcqIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf) /*{{{*/
601
bool descChanged = false;
602
// no .bz2 found, retry with .gz
603
if(Desc.URI.substr(Desc.URI.size()-3) == "bz2") {
604
Desc.URI = Desc.URI.substr(0,Desc.URI.size()-3) + "gz";
606
new pkgAcqIndex(Owner, RealURI, Desc.Description,Desc.ShortDesc,
607
ExpectedHash, string(".gz"));
610
// no .gz found, retry with uncompressed
611
else if(Desc.URI.substr(Desc.URI.size()-2) == "gz") {
612
Desc.URI = Desc.URI.substr(0,Desc.URI.size()-2);
614
new pkgAcqIndex(Owner, RealURI, Desc.Description,Desc.ShortDesc,
615
ExpectedHash, string("plain"));
633
std::vector<std::string> types = APT::Configuration::getCompressionTypes();
635
for (std::vector<std::string>::const_iterator t = types.begin();
636
t != types.end(); t++)
638
// jump over all already tried compression types
639
const unsigned int nameLen = Desc.URI.size() - (*t).size();
640
if(Desc.URI.substr(nameLen) != *t)
643
// we want to try it with the next extension (and make sure to
644
// not skip over the end)
646
if (t == types.end())
649
// queue new download
650
Desc.URI = Desc.URI.substr(0, nameLen) + *t;
651
new pkgAcqIndex(Owner, RealURI, Desc.Description, Desc.ShortDesc,
652
ExpectedHash, string(".").append(*t));
619
654
Status = StatDone;
620
655
Complete = false;
632
667
Item::Failed(Message,Cnf);
636
670
// AcqIndex::Done - Finished a fetch /*{{{*/
637
671
// ---------------------------------------------------------------------
638
672
/* This goes through a number of states.. On the initial fetch the
715
749
string compExt = flExtension(flNotDir(URI(Desc.URI).Path));
716
const char *decompProg;
718
decompProg = "bzip2";
719
else if(compExt == "gz")
752
// get the binary name for your used compression type
753
decompProg = _config->Find(string("Acquire::CompressionTypes::").append(compExt),"");
754
if(decompProg.empty() == false);
721
755
// flExtensions returns the full name if no extension is found
722
756
// this is why we have this complicated compare operation here
723
757
// FIMXE: add a new flJustExtension() that return "" if no
733
767
Decompression = true;
734
768
DestFile += ".decomp";
735
Desc.URI = string(decompProg) + ":" + FileName;
769
Desc.URI = decompProg + ":" + FileName;
771
Mode = decompProg.c_str();
740
774
// AcqIndexTrans::pkgAcqIndexTrans - Constructor /*{{{*/
741
775
// ---------------------------------------------------------------------
742
776
/* The Translation file is added to the queue */
745
779
: pkgAcqIndex(Owner, URI, URIDesc, ShortDesc, HashString(), "")
750
783
// AcqIndexTrans::Failed - Silence failure messages for missing files /*{{{*/
751
784
// ---------------------------------------------------------------------
765
798
Item::Failed(Message,Cnf);
769
pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner,
801
pkgAcqMetaSig::pkgAcqMetaSig(pkgAcquire *Owner, /*{{{*/
770
802
string URI,string URIDesc,string ShortDesc,
771
803
string MetaIndexURI, string MetaIndexURIDesc,
772
804
string MetaIndexShortDesc,
858
void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
890
void pkgAcqMetaSig::Failed(string Message,pkgAcquire::MethodConfig *Cnf)/*{{{*/
860
892
string Final = _config->FindDir("Dir::State::lists") + URItoFileName(RealURI);
892
924
Item::Failed(Message,Cnf);
895
pkgAcqMetaIndex::pkgAcqMetaIndex(pkgAcquire *Owner,
927
pkgAcqMetaIndex::pkgAcqMetaIndex(pkgAcquire *Owner, /*{{{*/
896
928
string URI,string URIDesc,string ShortDesc,
898
930
const vector<struct IndexTarget*>* IndexTargets,
928
959
return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime);
931
void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string Hash,
962
void pkgAcqMetaIndex::Done(string Message,unsigned long Size,string Hash, /*{{{*/
932
963
pkgAcquire::MethodConfig *Cfg)
934
965
Item::Done(Message,Size,Hash,Cfg);
1008
1039
chmod(FinalFile.c_str(),0644);
1009
1040
DestFile = FinalFile;
1012
void pkgAcqMetaIndex::AuthDone(string Message)
1043
void pkgAcqMetaIndex::AuthDone(string Message) /*{{{*/
1014
1045
// At this point, the gpgv method has succeeded, so there is a
1015
1046
// valid signature from a key in the trusted keyring. We
1042
1073
Rename(SigFile,VerifiedSigFile);
1043
1074
chmod(VerifiedSigFile.c_str(),0644);
1046
void pkgAcqMetaIndex::QueueIndexes(bool verify)
1077
void pkgAcqMetaIndex::QueueIndexes(bool verify) /*{{{*/
1048
1079
for (vector <struct IndexTarget*>::const_iterator Target = IndexTargets->begin();
1049
1080
Target != IndexTargets->end();
1085
1116
(*Target)->ShortDesc, ExpectedIndexHash);
1089
bool pkgAcqMetaIndex::VerifyVendor(string Message)
1120
bool pkgAcqMetaIndex::VerifyVendor(string Message) /*{{{*/
1091
1122
// // Maybe this should be made available from above so we don't have
1092
1123
// // to read and parse it every time?
1146
1177
Transformed = "";
1149
if (_config->FindB("Acquire::Check-Valid-Until", true)) {
1150
if (MetaIndexParser->GetValidUntil() > 0 &&
1151
time(NULL) > MetaIndexParser->GetValidUntil()) {
1152
return _error->Error(_("Release file expired, ignoring %s (valid until %s)"),
1154
TimeRFC1123(MetaIndexParser->GetValidUntil()).c_str());
1158
1180
if (_config->FindB("Debug::pkgAcquire::Auth", false))
1160
1182
std::cerr << "Got Codename: " << MetaIndexParser->GetDist() << std::endl;
1172
1194
// return false;
1173
1195
if (!Transformed.empty())
1175
_error->Warning(_("Conflicting distribution: %s (expected %s but got %s)"),
1197
_error->Warning("Conflicting distribution: %s (expected %s but got %s)",
1176
1198
Desc.Description.c_str(),
1177
1199
Transformed.c_str(),
1178
1200
MetaIndexParser->GetDist().c_str());
1185
// pkgAcqMetaIndex::Failed - no Release file present or no signature
1186
// file present /*{{{*/
1207
// pkgAcqMetaIndex::Failed - no Release file present or no signature file present /*{{{*/
1187
1208
// ---------------------------------------------------------------------
1189
1210
void pkgAcqMetaIndex::Failed(string Message,pkgAcquire::MethodConfig *Cnf)
1220
1241
// back to queueing Packages files without verification
1221
1242
QueueIndexes(false);
1226
1245
// AcqArchive::AcqArchive - Constructor /*{{{*/
1227
1246
// ---------------------------------------------------------------------
1228
1247
/* This just sets up the initial fetch environment and queues the first
1508
// AcqArchive::IsTrusted - Determine whether this archive comes from a
1509
// trusted source /*{{{*/
1527
// AcqArchive::IsTrusted - Determine whether this archive comes from a trusted source /*{{{*/
1510
1528
// ---------------------------------------------------------------------
1511
1529
bool pkgAcqArchive::IsTrusted()
1513
1531
return Trusted;
1516
1534
// AcqArchive::Finished - Fetching has finished, tidy up /*{{{*/
1517
1535
// ---------------------------------------------------------------------