apt  2.2.4
About: Apt (Advanced Package Tool) is a management system for software packages (Debian/Ubuntu). Release series 2.2.
  Fossies Dox: apt-2.2.4.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

indexcopy.cc
Go to the documentation of this file.
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 /* ######################################################################
4 
5  Index Copying - Aid for copying and verifying the index files
6 
7  This class helps apt-cache reconstruct a damaged index files.
8 
9  ##################################################################### */
10  /*}}}*/
11 // Include Files /*{{{*/
12 #include <config.h>
13 
15 #include <apt-pkg/cdrom.h>
16 #include <apt-pkg/configuration.h>
17 #include <apt-pkg/debmetaindex.h>
18 #include <apt-pkg/error.h>
19 #include <apt-pkg/fileutl.h>
20 #include <apt-pkg/gpgv.h>
21 #include <apt-pkg/hashes.h>
22 #include <apt-pkg/metaindex.h>
23 #include <apt-pkg/progress.h>
24 #include <apt-pkg/strutl.h>
25 #include <apt-pkg/tagfile.h>
26 
27 #include <iostream>
28 #include <sstream>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/stat.h>
33 #include <unistd.h>
34 
35 #include "indexcopy.h"
36 #include <apti18n.h>
37  /*}}}*/
38 
39 using namespace std;
40 
41 // IndexCopy::CopyPackages - Copy the package files from the CD /*{{{*/
42 // ---------------------------------------------------------------------
43 /* */
44 bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
45  pkgCdromStatus *log)
46 {
47  OpProgress *Progress = NULL;
48  if (List.empty() == true)
49  return true;
50 
51  if(log)
52  Progress = log->GetOpProgress();
53 
54  bool NoStat = _config->FindB("APT::CDROM::Fast",false);
55  bool Debug = _config->FindB("Debug::aptcdrom",false);
56 
57  // Prepare the progress indicator
58  off_t TotalSize = 0;
59  std::vector<APT::Configuration::Compressor> const compressor = APT::Configuration::getCompressors();
60  for (auto const &F : List)
61  {
62  struct stat Buf;
63  bool found = false;
64  auto const file = F + GetFileName();
65  for (auto const &c : compressor)
66  {
67  if (stat((file + c.Extension).c_str(), &Buf) != 0)
68  continue;
69  found = true;
70  break;
71  }
72 
73  if (found == false)
74  return _error->Errno("stat", "Stat failed for %s", file.c_str());
75  TotalSize += Buf.st_size;
76  }
77 
78  off_t CurrentSize = 0;
79  unsigned int NotFound = 0;
80  unsigned int WrongSize = 0;
81  unsigned int Packages = 0;
82  for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
83  {
84  std::string OrigPath(*I,CDROM.length());
85 
86  // Open the package file
88  off_t const FileSize = Pkg.Size();
89 
90  pkgTagFile Parser(&Pkg);
91  if (Pkg.IsOpen() == false || Pkg.Failed())
92  return false;
93 
94  // Open the output file
95  char S[400];
96  snprintf(S,sizeof(S),"cdrom:[%s]/%s%s",Name.c_str(),
97  (*I).c_str() + CDROM.length(),GetFileName());
98  string TargetF = _config->FindDir("Dir::State::lists") + "partial/";
99  TargetF += URItoFileName(S);
100  FileFd Target;
101  if (_config->FindB("APT::CDROM::NoAct",false) == true)
102  {
103  TargetF = "/dev/null";
104  Target.Open(TargetF,FileFd::WriteExists);
105  } else {
106  Target.Open(TargetF,FileFd::WriteAtomic);
107  }
108  if (Target.IsOpen() == false || Target.Failed())
109  return false;
110 
111  // Setup the progress meter
112  if(Progress)
113  Progress->OverallProgress(CurrentSize,TotalSize,FileSize,
114  string("Reading ") + Type() + " Indexes");
115 
116  // Parse
117  if(Progress)
118  Progress->SubProgress(Pkg.Size());
120  this->Section = &Section;
121  string Prefix;
122  unsigned long Hits = 0;
123  unsigned long Chop = 0;
124  while (Parser.Step(Section) == true)
125  {
126  if(Progress)
127  Progress->Progress(Parser.Offset());
128  string File;
129  unsigned long long Size;
130  if (GetFile(File,Size) == false)
131  return false;
132 
133  if (Chop != 0)
134  File = OrigPath + ChopDirs(File,Chop);
135 
136  // See if the file exists
137  if (NoStat == false || Hits < 10)
138  {
139  // Attempt to fix broken structure
140  if (Hits == 0)
141  {
142  if (ReconstructPrefix(Prefix,OrigPath,CDROM,File) == false &&
143  ReconstructChop(Chop,*I,File) == false)
144  {
145  if (Debug == true)
146  clog << "Missed: " << File << endl;
147  NotFound++;
148  continue;
149  }
150  if (Chop != 0)
151  File = OrigPath + ChopDirs(File,Chop);
152  }
153 
154  // Get the size
155  struct stat Buf;
156  if (stat((CDROM + Prefix + File).c_str(),&Buf) != 0 ||
157  Buf.st_size == 0)
158  {
159  bool Mangled = false;
160  // Attempt to fix busted symlink support for one instance
161  string OrigFile = File;
162  string::size_type Start = File.find("binary-");
163  string::size_type End = File.find("/",Start+3);
164  if (Start != string::npos && End != string::npos)
165  {
166  File.replace(Start,End-Start,"binary-all");
167  Mangled = true;
168  }
169 
170  if (Mangled == false ||
171  stat((CDROM + Prefix + File).c_str(),&Buf) != 0)
172  {
173  if (Debug == true)
174  clog << "Missed(2): " << OrigFile << endl;
175  NotFound++;
176  continue;
177  }
178  }
179 
180  // Size match
181  if ((unsigned long long)Buf.st_size != Size)
182  {
183  if (Debug == true)
184  clog << "Wrong Size: " << File << endl;
185  WrongSize++;
186  continue;
187  }
188  }
189 
190  Packages++;
191  Hits++;
192 
193  if (RewriteEntry(Target, File) == false)
194  return false;
195  }
196 
197  if (Debug == true)
198  cout << " Processed by using Prefix '" << Prefix << "' and chop " << Chop << endl;
199 
200  if (_config->FindB("APT::CDROM::NoAct",false) == false)
201  {
202  // Move out of the partial directory
203  Target.Close();
204  string FinalF = _config->FindDir("Dir::State::lists");
205  FinalF += URItoFileName(S);
206  if (rename(TargetF.c_str(),FinalF.c_str()) != 0)
207  return _error->Errno("rename","Failed to rename");
208  ChangeOwnerAndPermissionOfFile("CopyPackages", FinalF.c_str(), "root", ROOT_GROUP, 0644);
209  }
210 
211  /* Mangle the source to be in the proper notation with
212  prefix dist [component] */
213  *I = string(*I,Prefix.length());
214  ConvertToSourceList(CDROM,*I);
215  *I = Prefix + ' ' + *I;
216 
217  CurrentSize += FileSize;
218  }
219  if(Progress)
220  Progress->Done();
221 
222  // Some stats
223  if(log) {
224  stringstream msg;
225  if(NotFound == 0 && WrongSize == 0)
226  ioprintf(msg, _("Wrote %i records.\n"), Packages);
227  else if (NotFound != 0 && WrongSize == 0)
228  ioprintf(msg, _("Wrote %i records with %i missing files.\n"),
229  Packages, NotFound);
230  else if (NotFound == 0 && WrongSize != 0)
231  ioprintf(msg, _("Wrote %i records with %i mismatched files\n"),
232  Packages, WrongSize);
233  if (NotFound != 0 && WrongSize != 0)
234  ioprintf(msg, _("Wrote %i records with %i missing files and %i mismatched files\n"), Packages, NotFound, WrongSize);
235  }
236 
237  if (Packages == 0)
238  _error->Warning("No valid records were found.");
239 
240  if (NotFound + WrongSize > 10)
241  _error->Warning("A lot of entries were discarded, something may be wrong.\n");
242 
243  return true;
244 }
245  /*}}}*/
246 // IndexCopy::ChopDirs - Chop off the leading directory components /*{{{*/
247 // ---------------------------------------------------------------------
248 /* */
249 string IndexCopy::ChopDirs(string Path,unsigned int Depth)
250 {
251  string::size_type I = 0;
252  do
253  {
254  I = Path.find('/',I+1);
255  Depth--;
256  }
257  while (I != string::npos && Depth != 0);
258 
259  if (I == string::npos)
260  return string();
261 
262  return string(Path,I+1);
263 }
264  /*}}}*/
265 // IndexCopy::ReconstructPrefix - Fix strange prefixing /*{{{*/
266 // ---------------------------------------------------------------------
267 /* This prepends dir components from the path to the package files to
268  the path to the deb until it is found */
269 bool IndexCopy::ReconstructPrefix(string &Prefix,string OrigPath,string CD,
270  string File)
271 {
272  bool Debug = _config->FindB("Debug::aptcdrom",false);
273  unsigned int Depth = 1;
274  string MyPrefix = Prefix;
275  while (1)
276  {
277  struct stat Buf;
278  if (stat((CD + MyPrefix + File).c_str(),&Buf) != 0)
279  {
280  if (Debug == true)
281  cout << "Failed, " << CD + MyPrefix + File << endl;
282  if (GrabFirst(OrigPath,MyPrefix,Depth++) == true)
283  continue;
284 
285  return false;
286  }
287  else
288  {
289  Prefix = MyPrefix;
290  return true;
291  }
292  }
293  return false;
294 }
295  /*}}}*/
296 // IndexCopy::ReconstructChop - Fixes bad source paths /*{{{*/
297 // ---------------------------------------------------------------------
298 /* This removes path components from the filename and prepends the location
299  of the package files until a file is found */
300 bool IndexCopy::ReconstructChop(unsigned long &Chop,string Dir,string File)
301 {
302  // Attempt to reconstruct the filename
303  unsigned long Depth = 0;
304  while (1)
305  {
306  struct stat Buf;
307  if (stat((Dir + File).c_str(),&Buf) != 0)
308  {
309  File = ChopDirs(File,1);
310  Depth++;
311  if (File.empty() == false)
312  continue;
313  return false;
314  }
315  else
316  {
317  Chop = Depth;
318  return true;
319  }
320  }
321  return false;
322 }
323  /*}}}*/
324 // IndexCopy::ConvertToSourceList - Convert a Path to a sourcelist /*{{{*/
325 // ---------------------------------------------------------------------
326 /* We look for things in dists/ notation and convert them to
327  <dist> <component> form otherwise it is left alone. This also strips
328  the CD path.
329 
330  This implements a regex sort of like:
331  (.*)/dists/([^/]*)/(.*)/binary-*
332  ^ ^ ^- Component
333  | |-------- Distribution
334  |------------------- Path
335 
336  It was deciced to use only a single word for dist (rather than say
337  unstable/non-us) to increase the chance that each CD gets a single
338  line in sources.list.
339  */
340 void IndexCopy::ConvertToSourceList(string CD,string &Path)
341 {
342  // Strip the cdrom base path
343  Path = string(Path,CD.length());
344  if (Path.empty() == true)
345  Path = "/";
346 
347  // Too short to be a dists/ type
348  if (Path.length() < strlen("dists/"))
349  return;
350 
351  // Not a dists type.
352  if (stringcmp(Path.c_str(),Path.c_str()+strlen("dists/"),"dists/") != 0)
353  return;
354 
355  // Isolate the dist
356  string::size_type Slash = strlen("dists/");
357  string::size_type Slash2 = Path.find('/',Slash + 1);
358  if (Slash2 == string::npos || Slash2 + 2 >= Path.length())
359  return;
360  string Dist = string(Path,Slash,Slash2 - Slash);
361 
362  // Isolate the component
363  Slash = Slash2;
364  for (unsigned I = 0; I != 10; I++)
365  {
366  Slash = Path.find('/',Slash+1);
367  if (Slash == string::npos || Slash + 2 >= Path.length())
368  return;
369  string Comp = string(Path,Slash2+1,Slash - Slash2-1);
370 
371  // Verify the trailing binary- bit
372  string::size_type BinSlash = Path.find('/',Slash + 1);
373  if (Slash == string::npos)
374  return;
375  string Binary = string(Path,Slash+1,BinSlash - Slash-1);
376 
377  if (strncmp(Binary.c_str(), "binary-", strlen("binary-")) == 0)
378  {
379  Binary.erase(0, strlen("binary-"));
380  if (APT::Configuration::checkArchitecture(Binary) == false)
381  continue;
382  }
383  else if (Binary != "source")
384  continue;
385 
386  Path = Dist + ' ' + Comp;
387  return;
388  }
389 }
390  /*}}}*/
391 // IndexCopy::GrabFirst - Return the first Depth path components /*{{{*/
392 // ---------------------------------------------------------------------
393 /* */
394 bool IndexCopy::GrabFirst(string Path,string &To,unsigned int Depth)
395 {
396  string::size_type I = 0;
397  do
398  {
399  I = Path.find('/',I+1);
400  Depth--;
401  }
402  while (I != string::npos && Depth != 0);
403 
404  if (I == string::npos)
405  return false;
406 
407  To = string(Path,0,I+1);
408  return true;
409 }
410  /*}}}*/
411 // PackageCopy::GetFile - Get the file information from the section /*{{{*/
412 // ---------------------------------------------------------------------
413 /* */
414 bool PackageCopy::GetFile(string &File,unsigned long long &Size)
415 {
416  File = Section->FindS("Filename");
417  Size = Section->FindI("Size");
418  if (File.empty() || Size == 0)
419  return _error->Error("Cannot find filename or size tag");
420  return true;
421 }
422  /*}}}*/
423 // PackageCopy::RewriteEntry - Rewrite the entry with a new filename /*{{{*/
424 bool PackageCopy::RewriteEntry(FileFd &Target,string const &File)
425 {
426  std::vector<pkgTagSection::Tag> Changes;
427  Changes.push_back(pkgTagSection::Tag::Rewrite("Filename", File));
428 
429  if (Section->Write(Target, TFRewritePackageOrder, Changes) == false)
430  return false;
431  return Target.Write("\n", 1);
432 }
433  /*}}}*/
434 // SourceCopy::GetFile - Get the file information from the section /*{{{*/
435 // ---------------------------------------------------------------------
436 /* */
437 bool SourceCopy::GetFile(string &File,unsigned long long &Size)
438 {
439  string Files;
440 
441  for (char const *const *type = HashString::SupportedHashes(); *type != NULL; ++type)
442  {
443  // derive field from checksum type
444  std::string checksumField("Checksums-");
445  if (strcmp(*type, "MD5Sum") == 0)
446  checksumField = "Files"; // historic name for MD5 checksums
447  else
448  checksumField.append(*type);
449 
450  Files = Section->FindS(checksumField.c_str());
451  if (Files.empty() == false)
452  break;
453  }
454  if (Files.empty() == true)
455  return false;
456 
457  // Stash the / terminated directory prefix
458  string Base = Section->FindS("Directory");
459  if (Base.empty() == false && Base[Base.length()-1] != '/')
460  Base += '/';
461 
462  // Read the first file triplet
463  const char *C = Files.c_str();
464  string sSize;
465  string MD5Hash;
466 
467  // Parse each of the elements
468  if (ParseQuoteWord(C,MD5Hash) == false ||
469  ParseQuoteWord(C,sSize) == false ||
470  ParseQuoteWord(C,File) == false)
471  return _error->Error("Error parsing file record");
472 
473  // Parse the size and append the directory
474  Size = strtoull(sSize.c_str(), NULL, 10);
475  File = Base + File;
476  return true;
477 }
478  /*}}}*/
479 // SourceCopy::RewriteEntry - Rewrite the entry with a new filename /*{{{*/
480 bool SourceCopy::RewriteEntry(FileFd &Target, std::string const &File)
481 {
482  string const Dir(File,0,File.rfind('/'));
483  std::vector<pkgTagSection::Tag> Changes;
484  Changes.push_back(pkgTagSection::Tag::Rewrite("Directory", Dir));
485 
486  if (Section->Write(Target, TFRewriteSourceOrder, Changes) == false)
487  return false;
488  return Target.Write("\n", 1);
489 }
490  /*}}}*/
491 // SigVerify::Verify - Verify a files md5sum against its metaindex /*{{{*/
492 bool SigVerify::Verify(string prefix, string file, metaIndex *MetaIndex)
493 {
494  const metaIndex::checkSum *Record = MetaIndex->Lookup(file);
495  bool const Debug = _config->FindB("Debug::aptcdrom",false);
496 
497  // we skip non-existing files in the verifcation of the Release file
498  // as non-existing files do not harm, but a warning scares people and
499  // makes it hard to strip unneeded files from an ISO like uncompressed
500  // indexes as it is done on the mirrors (see also LP: #255545 )
501  if(!RealFileExists(prefix+file))
502  {
503  if (Debug == true)
504  cout << "Skipping nonexistent in " << prefix << " file " << file << std::endl;
505  return true;
506  }
507 
508  if (!Record)
509  {
510  _error->Warning(_("Can't find authentication record for: %s"), file.c_str());
511  return false;
512  }
513 
514  if (!Record->Hashes.VerifyFile(prefix+file))
515  {
516  _error->Warning(_("Hash mismatch for: %s"),file.c_str());
517  return false;
518  }
519 
520  if(Debug == true)
521  {
522  cout << "File: " << prefix+file << endl
523  << "Expected Hash " << endl;
524  for (HashStringList::const_iterator hs = Record->Hashes.begin(); hs != Record->Hashes.end(); ++hs)
525  std::cout << "\t- " << hs->toStr() << std::endl;
526  }
527 
528  return true;
529 }
530  /*}}}*/
531 bool SigVerify::CopyMetaIndex(string CDROM, string CDName, /*{{{*/
532  string prefix, string file)
533 {
534  char S[400];
535  snprintf(S,sizeof(S),"cdrom:[%s]/%s%s",CDName.c_str(),
536  (prefix).c_str() + CDROM.length(),file.c_str());
537  string TargetF = _config->FindDir("Dir::State::lists");
538  TargetF += URItoFileName(S);
539 
540  FileFd Target;
541  FileFd Rel;
542  Target.Open(TargetF,FileFd::WriteAtomic);
543  Rel.Open(prefix + file,FileFd::ReadOnly);
544  if (CopyFile(Rel,Target) == false || Target.Close() == false)
545  return _error->Error("Copying of '%s' for '%s' from '%s' failed", file.c_str(), CDName.c_str(), prefix.c_str());
546  ChangeOwnerAndPermissionOfFile("CopyPackages", TargetF.c_str(), "root", ROOT_GROUP, 0644);
547 
548  return true;
549 }
550  /*}}}*/
551 bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList, /*{{{*/
552  vector<string> /*PkgList*/,vector<string> /*SrcList*/)
553 {
554  if (SigList.empty() == true)
555  return true;
556 
557  bool Debug = _config->FindB("Debug::aptcdrom",false);
558 
559  // Read all Release files
560  for (vector<string>::iterator I = SigList.begin(); I != SigList.end(); ++I)
561  {
562  if(Debug)
563  cout << "Signature verify for: " << *I << endl;
564 
565  metaIndex *MetaIndex = new debReleaseIndex("","", {});
566  string prefix = *I;
567 
568  string const releasegpg = *I+"Release.gpg";
569  string const release = *I+"Release";
570  string const inrelease = *I+"InRelease";
571  bool useInRelease = true;
572 
573  // a Release.gpg without a Release should never happen
574  if (RealFileExists(inrelease) == true)
575  ;
576  else if(RealFileExists(release) == false || RealFileExists(releasegpg) == false)
577  {
578  delete MetaIndex;
579  continue;
580  }
581  else
582  useInRelease = false;
583 
584  pid_t pid = ExecFork();
585  if(pid < 0) {
586  _error->Error("Fork failed");
587  return false;
588  }
589  if(pid == 0)
590  {
591  if (useInRelease == true)
592  ExecGPGV(inrelease, inrelease);
593  else
594  ExecGPGV(release, releasegpg);
595  }
596 
597  if(!ExecWait(pid, "gpgv")) {
598  _error->Warning("Signature verification failed for: %s",
599  (useInRelease ? inrelease.c_str() : releasegpg.c_str()));
600  // something went wrong, don't copy the Release.gpg
601  // FIXME: delete any existing gpg file?
602  delete MetaIndex;
603  continue;
604  }
605 
606  // Open the Release file and add it to the MetaIndex
607  std::string ErrorText;
608  if(MetaIndex->Load(release, &ErrorText) == false)
609  {
610  _error->Error("%s", ErrorText.c_str());
611  return false;
612  }
613 
614  // go over the Indexfiles and see if they verify
615  // if so, remove them from our copy of the lists
616  vector<string> keys = MetaIndex->MetaKeys();
617  for (vector<string>::iterator I = keys.begin(); I != keys.end(); ++I)
618  {
619  if(!Verify(prefix,*I, MetaIndex)) {
620  // something went wrong, don't copy the Release.gpg
621  // FIXME: delete any existing gpg file?
622  _error->Discard();
623  continue;
624  }
625  }
626 
627  // we need a fresh one for the Release.gpg
628  delete MetaIndex;
629 
630  // everything was fine, copy the Release and Release.gpg file
631  if (useInRelease == true)
632  CopyMetaIndex(CDROM, Name, prefix, "InRelease");
633  else
634  {
635  CopyMetaIndex(CDROM, Name, prefix, "Release");
636  CopyMetaIndex(CDROM, Name, prefix, "Release.gpg");
637  }
638  }
639 
640  return true;
641 }
642  /*}}}*/
643 bool TranslationsCopy::CopyTranslations(string CDROM,string Name, /*{{{*/
644  vector<string> &List, pkgCdromStatus *log)
645 {
646  OpProgress *Progress = NULL;
647  if (List.empty() == true)
648  return true;
649 
650  if(log)
651  Progress = log->GetOpProgress();
652 
653  bool Debug = _config->FindB("Debug::aptcdrom",false);
654 
655  // Prepare the progress indicator
656  off_t TotalSize = 0;
657  std::vector<APT::Configuration::Compressor> const compressor = APT::Configuration::getCompressors();
658  for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
659  {
660  struct stat Buf;
661  bool found = false;
662  std::string file = *I;
663  for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressor.begin();
664  c != compressor.end(); ++c)
665  {
666  if (stat((file + c->Extension).c_str(), &Buf) != 0)
667  continue;
668  found = true;
669  break;
670  }
671 
672  if (found == false)
673  return _error->Errno("stat", "Stat failed for %s", file.c_str());
674  TotalSize += Buf.st_size;
675  }
676 
677  off_t CurrentSize = 0;
678  unsigned int NotFound = 0;
679  unsigned int WrongSize = 0;
680  unsigned int Packages = 0;
681  for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
682  {
683  // Open the package file
685  off_t const FileSize = Pkg.Size();
686 
687  pkgTagFile Parser(&Pkg);
688  if (Pkg.IsOpen() == false || Pkg.Failed())
689  return false;
690 
691  // Open the output file
692  char S[400];
693  snprintf(S,sizeof(S),"cdrom:[%s]/%s",Name.c_str(),
694  (*I).c_str() + CDROM.length());
695  string TargetF = _config->FindDir("Dir::State::lists") + "partial/";
696  TargetF += URItoFileName(S);
697  FileFd Target;
698  if (_config->FindB("APT::CDROM::NoAct",false) == true)
699  {
700  TargetF = "/dev/null";
701  Target.Open(TargetF,FileFd::WriteExists);
702  } else {
703  Target.Open(TargetF,FileFd::WriteAtomic);
704  }
705  if (Pkg.IsOpen() == false || Pkg.Failed())
706  return false;
707 
708  // Setup the progress meter
709  if(Progress)
710  Progress->OverallProgress(CurrentSize,TotalSize,FileSize,
711  string("Reading Translation Indexes"));
712 
713  // Parse
714  if(Progress)
715  Progress->SubProgress(Pkg.Size());
717  this->Section = &Section;
718  string Prefix;
719  unsigned long Hits = 0;
720  while (Parser.Step(Section) == true)
721  {
722  if(Progress)
723  Progress->Progress(Parser.Offset());
724 
725  if (Section.Write(Target) == false || Target.Write("\n", 1) == false)
726  return false;
727 
728  Packages++;
729  Hits++;
730  }
731 
732  if (Debug == true)
733  cout << " Processed by using Prefix '" << Prefix << "' and chop " << endl;
734 
735  if (_config->FindB("APT::CDROM::NoAct",false) == false)
736  {
737  // Move out of the partial directory
738  Target.Close();
739  string FinalF = _config->FindDir("Dir::State::lists");
740  FinalF += URItoFileName(S);
741  if (rename(TargetF.c_str(),FinalF.c_str()) != 0)
742  return _error->Errno("rename","Failed to rename");
743  ChangeOwnerAndPermissionOfFile("CopyTranslations", FinalF.c_str(), "root", ROOT_GROUP, 0644);
744  }
745 
746  CurrentSize += FileSize;
747  }
748  if(Progress)
749  Progress->Done();
750 
751  // Some stats
752  if(log) {
753  stringstream msg;
754  if(NotFound == 0 && WrongSize == 0)
755  ioprintf(msg, _("Wrote %i records.\n"), Packages);
756  else if (NotFound != 0 && WrongSize == 0)
757  ioprintf(msg, _("Wrote %i records with %i missing files.\n"),
758  Packages, NotFound);
759  else if (NotFound == 0 && WrongSize != 0)
760  ioprintf(msg, _("Wrote %i records with %i mismatched files\n"),
761  Packages, WrongSize);
762  if (NotFound != 0 && WrongSize != 0)
763  ioprintf(msg, _("Wrote %i records with %i missing files and %i mismatched files\n"), Packages, NotFound, WrongSize);
764  }
765 
766  if (Packages == 0)
767  _error->Warning("No valid records were found.");
768 
769  if (NotFound + WrongSize > 10)
770  _error->Warning("A lot of entries were discarded, something may be wrong.\n");
771 
772  return true;
773 }
774  /*}}}*/
775 
776 IndexCopy::IndexCopy() : d(nullptr), Section(nullptr) {}
778 
783 TranslationsCopy::TranslationsCopy() : d(nullptr), Section(nullptr) {}
785 SigVerify::SigVerify() : d(NULL) {}
static bool std::string const metaIndex const *const pkgAcqMetaClearSig *const pkgAcquire::Item *const I
static char const *const msg
void ExecGPGV(std::string const &File, std::string const &FileGPG, int const &statusfd, int fd[2], std::string const &key)
generates and run the command to verify a file with gpgv
Definition: gpgv.cc:148
Definition: fileutl.h:39
bool IsOpen()
Definition: fileutl.h:150
@ Auto
Definition: fileutl.h:78
@ WriteAtomic
Definition: fileutl.h:74
@ WriteExists
Definition: fileutl.h:70
@ ReadOnly
Definition: fileutl.h:59
bool Write(const void *From, unsigned long long Size)
Definition: fileutl.cc:2819
bool Failed()
Definition: fileutl.h:151
bool Open(std::string FileName, unsigned int const Mode, CompressMode Compress, unsigned long const AccessMode=0666)
Definition: fileutl.cc:2415
unsigned long long Size()
Definition: fileutl.cc:2967
bool Close()
Definition: fileutl.cc:2977
bool VerifyFile(std::string filename) const
Definition: hashes.cc:248
const_iterator begin() const
Definition: hashes.h:133
std::vector< HashString >::const_iterator const_iterator
Definition: hashes.h:130
const_iterator end() const
Definition: hashes.h:136
static APT_PURE const char ** SupportedHashes()
Definition: hashes.cc:135
pkgTagSection * Section
Definition: indexcopy.h:33
std::string ChopDirs(std::string Path, unsigned int Depth)
Definition: indexcopy.cc:249
virtual bool GetFile(std::string &Filename, unsigned long long &Size)=0
void ConvertToSourceList(std::string CD, std::string &Path)
Definition: indexcopy.cc:340
bool CopyPackages(std::string CDROM, std::string Name, std::vector< std::string > &List, pkgCdromStatus *log)
Definition: indexcopy.cc:44
virtual ~IndexCopy()
Definition: indexcopy.cc:777
bool ReconstructPrefix(std::string &Prefix, std::string OrigPath, std::string CD, std::string File)
Definition: indexcopy.cc:269
bool ReconstructChop(unsigned long &Chop, std::string Dir, std::string File)
Definition: indexcopy.cc:300
virtual bool RewriteEntry(FileFd &Target, std::string const &File)=0
bool GrabFirst(std::string Path, std::string &To, unsigned int Depth)
Definition: indexcopy.cc:394
virtual const char * GetFileName()=0
virtual const char * Type()=0
virtual void Done()
Definition: progress.h:60
void OverallProgress(unsigned long long Current, unsigned long long Total, unsigned long long Size, const std::string &Op)
Definition: progress.cc:55
void Progress(unsigned long long Current)
Definition: progress.cc:43
void SubProgress(unsigned long long SubTotal, const std::string &Op="", float const Percent=-1)
Definition: progress.cc:73
virtual bool RewriteEntry(FileFd &Target, std::string const &File) APT_OVERRIDE
Definition: indexcopy.cc:424
virtual bool GetFile(std::string &Filename, unsigned long long &Size) APT_OVERRIDE
Definition: indexcopy.cc:414
virtual ~PackageCopy()
Definition: indexcopy.cc:780
APT_HIDDEN bool CopyMetaIndex(std::string CDROM, std::string CDName, std::string prefix, std::string file)
Definition: indexcopy.cc:531
APT_HIDDEN bool Verify(std::string prefix, std::string file, metaIndex *records)
Definition: indexcopy.cc:492
bool CopyAndVerify(std::string CDROM, std::string Name, std::vector< std::string > &SigList, std::vector< std::string > PkgList, std::vector< std::string > SrcList)
Definition: indexcopy.cc:551
virtual ~SigVerify()
Definition: indexcopy.cc:786
virtual bool RewriteEntry(FileFd &Target, std::string const &File) APT_OVERRIDE
Definition: indexcopy.cc:480
virtual ~SourceCopy()
Definition: indexcopy.cc:782
virtual bool GetFile(std::string &Filename, unsigned long long &Size) APT_OVERRIDE
Definition: indexcopy.cc:437
pkgTagSection * Section
Definition: indexcopy.h:88
bool CopyTranslations(std::string CDROM, std::string Name, std::vector< std::string > &List, pkgCdromStatus *log)
Definition: indexcopy.cc:643
virtual ~TranslationsCopy()
Definition: indexcopy.cc:784
std::vector< std::string > MetaKeys() const
Definition: metaindex.cc:105
checkSum * Lookup(std::string const &MetaKey) const
Definition: metaindex.cc:92
virtual bool Load(std::string const &Filename, std::string *const ErrorText)=0
virtual OpProgress * GetOpProgress()
Definition: cdrom.h:35
bool Step(pkgTagSection &Section)
Definition: tagfile.cc:204
unsigned long Offset()
Definition: tagfile.cc:163
std::string FindS(APT::StringView sv) const
Definition: tagfile.h:70
bool Write(FileFd &File, char const *const *const Order=NULL, std::vector< Tag > const &Rewrite=std::vector< Tag >()) const
Definition: tagfile.cc:999
APT_HIDDEN signed int FindI(Key key, signed long Default=0) const
Definition: tagfile.cc:776
Configuration * _config
bool ExecWait(pid_t Pid, const char *Name, bool Reap)
Definition: fileutl.cc:942
bool ChangeOwnerAndPermissionOfFile(char const *const requester, char const *const file, char const *const user, char const *const group, mode_t const mode)
Definition: fileutl.cc:1015
bool RealFileExists(string File)
Definition: fileutl.cc:337
bool CopyFile(FileFd &From, FileFd &To)
Definition: fileutl.cc:164
pid_t ExecFork()
Definition: fileutl.cc:881
APT_PUBLIC std::vector< Compressor > const getCompressors(bool const Cached=true)
Return a vector of Compressors supported for data.tar's.
APT_PUBLIC bool checkArchitecture(std::string const &Arch)
Are we interested in the given Architecture?
HashStringList Hashes
Definition: metaindex.h:26
static Tag Rewrite(std::string const &Name, std::string const &Data)
Definition: tagfile.cc:958
void ioprintf(ostream &out, const char *format,...)
Definition: strutl.cc:1433
string URItoFileName(const string &URI)
Definition: strutl.cc:553
int stringcmp(const char *A, const char *AEnd, const char *B, const char *BEnd)
Definition: strutl.cc:628
bool ParseQuoteWord(const char *&String, string &Res)
Definition: strutl.cc:288
const char ** TFRewritePackageOrder
const char ** TFRewriteSourceOrder