Преглед изворни кода

* added a BUGS file with known problem, added apt-cdrom support for translated package descriptions

Michael Vogt пре 21 година
родитељ
комит
22f8568d5f
5 измењених фајлова са 242 додато и 14 уклоњено
  1. 6 0
      BUGS
  2. 38 9
      apt-pkg/cdrom.cc
  3. 5 2
      apt-pkg/cdrom.h
  4. 180 3
      apt-pkg/indexcopy.cc
  5. 13 0
      apt-pkg/indexcopy.h

+ 6 - 0
BUGS

@@ -0,0 +1,6 @@
+
+DDTP problems:
+--------------
+- apt-get update clean the /var/lib/apt/lists dir 
+  from all Translation-$index that are not in the current
+  enviroment or Translations apt variable

+ 38 - 9
apt-pkg/cdrom.cc

@@ -30,12 +30,16 @@ using namespace std;
    search that short circuits when it his a package file in the dir.
    This speeds it up greatly as the majority of the size is in the
    binary-* sub dirs. */
-bool pkgCdrom::FindPackages(string CD,vector<string> &List,
-			    vector<string> &SList, vector<string> &SigList,
+bool pkgCdrom::FindPackages(string CD,
+			    vector<string> &List,
+			    vector<string> &SList, 
+			    vector<string> &SigList,
+			    vector<string> &TransList,
 			    string &InfoDir, pkgCdromStatus *log,
 			    unsigned int Depth)
 {
    static ino_t Inodes[9];
+   DIR *D;
 
    // if we have a look we "pulse" now
    if(log)
@@ -90,8 +94,28 @@ bool pkgCdrom::FindPackages(string CD,vector<string> &List,
       if (_config->FindB("APT::CDROM::Thorough",false) == false)
 	 return true;
    }
+
+   // see if we find translatin indexes
+   if (stat("i18n",&Buf) == 0)
+   {
+      D = opendir("i18n");
+      for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D))
+      {
+	 if(strstr(Dir->d_name,"Translation") != NULL) 
+	 {
+	    if (_config->FindB("Debug::aptcdrom",false) == true)
+	       std::clog << "found translations: " << Dir->d_name << "\n";
+	    string file = Dir->d_name;
+	    if(file.substr(file.size()-3,file.size()) == ".gz")
+	       file = file.substr(0,file.size()-3);
+	    TransList.push_back(CD+"i18n/"+ file);
+	 }
+      }
+      closedir(D);
+   }
+
    
-   DIR *D = opendir(".");
+   D = opendir(".");
    if (D == 0)
       return _error->Errno("opendir","Unable to read %s",CD.c_str());
    
@@ -127,7 +151,7 @@ bool pkgCdrom::FindPackages(string CD,vector<string> &List,
       Inodes[Depth] = Buf.st_ino;
 
       // Descend
-      if (FindPackages(CD + Dir->d_name,List,SList,SigList,InfoDir,log,Depth+1) == false)
+      if (FindPackages(CD + Dir->d_name,List,SList,SigList,TransList,InfoDir,log,Depth+1) == false)
 	 break;
 
       if (chdir(CD.c_str()) != 0)
@@ -609,9 +633,10 @@ bool pkgCdrom::Add(pkgCdromStatus *log)
    vector<string> List;
    vector<string> SourceList;
    vector<string> SigList;
+   vector<string> TransList;
    string StartDir = SafeGetCWD();
    string InfoDir;
-   if (FindPackages(CDROM,List,SourceList, SigList,InfoDir,log) == false)
+   if (FindPackages(CDROM,List,SourceList, SigList,TransList,InfoDir,log) == false)
    {
       log->Update("\n");
       return false;
@@ -639,11 +664,13 @@ bool pkgCdrom::Add(pkgCdromStatus *log)
    DropRepeats(List,"Packages");
    DropRepeats(SourceList,"Sources");
    DropRepeats(SigList,"Release.gpg");
+   DropRepeats(TransList,"");
    if(log) {
       msg.str("");
-      ioprintf(msg, _("Found %i package indexes, %i source indexes and "
-		      "%i signatures\n"), 
-	       List.size(), SourceList.size(), SigList.size());
+      ioprintf(msg, _("Found %i package indexes, %i source indexes, "
+		      "%i translation indexes and %i signatures\n"), 
+	       List.size(), SourceList.size(), TransList.size(),
+	       SigList.size());
       log->Update(msg.str(), STEP_SCAN);
    }
 
@@ -727,8 +754,10 @@ bool pkgCdrom::Add(pkgCdromStatus *log)
    // Copy the package files to the state directory
    PackageCopy Copy;
    SourceCopy SrcCopy;
+   TranslationsCopy TransCopy;
    if (Copy.CopyPackages(CDROM,Name,List, log) == false ||
-       SrcCopy.CopyPackages(CDROM,Name,SourceList, log) == false)
+       SrcCopy.CopyPackages(CDROM,Name,SourceList, log) == false ||
+       TransCopy.CopyTranslations(CDROM,Name,TransList, log) == false)
       return false;
 
    // reduce the List so that it takes less space in sources.list

+ 5 - 2
apt-pkg/cdrom.h

@@ -50,8 +50,11 @@ class pkgCdrom
    };
 
 
-   bool FindPackages(string CD,vector<string> &List,
-		     vector<string> &SList, vector<string> &SigList,
+   bool FindPackages(string CD,
+		     vector<string> &List,
+		     vector<string> &SList, 
+		     vector<string> &SigList,
+		     vector<string> &TransList,
 		     string &InfoDir, pkgCdromStatus *log,
 		     unsigned int Depth = 0);
    bool DropBinaryArch(vector<string> &List);

+ 180 - 3
apt-pkg/indexcopy.cc

@@ -32,6 +32,8 @@
 
 using namespace std;
 
+
+
 // IndexCopy::CopyPackages - Copy the package files from the CD		/*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -512,10 +514,10 @@ bool SourceCopy::RewriteEntry(FILE *Target,string File)
    fputc('\n',Target);
    return true;
 }
-
-
 									/*}}}*/
-
+// SigVerify::Verify - Verify a files md5sum against its metaindex     	/*{{{*/
+// ---------------------------------------------------------------------
+/* */
 bool SigVerify::Verify(string prefix, string file, indexRecords *MetaIndex)
 {
    const indexRecords::checkSum *Record = MetaIndex->Lookup(file);
@@ -670,3 +672,178 @@ bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList,
 
    return true;
 }
+
+
+bool TranslationsCopy::CopyTranslations(string CDROM,string Name,vector<string> &List,
+			     pkgCdromStatus *log)
+{
+   OpProgress *Progress = NULL;
+   if (List.size() == 0)
+      return true;
+   
+   if(log) 
+      Progress = log->GetOpProgress();
+   
+   bool Debug = _config->FindB("Debug::aptcdrom",false);
+   
+   // Prepare the progress indicator
+   unsigned long TotalSize = 0;
+   for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
+   {
+      struct stat Buf;
+      if (stat(string(*I).c_str(),&Buf) != 0 &&
+	  stat(string(*I + ".gz").c_str(),&Buf) != 0)
+	 return _error->Errno("stat","Stat failed for %s",
+			      string(*I).c_str());
+      TotalSize += Buf.st_size;
+   }	
+
+   unsigned long CurrentSize = 0;
+   unsigned int NotFound = 0;
+   unsigned int WrongSize = 0;
+   unsigned int Packages = 0;
+   for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
+   {      
+      string OrigPath = string(*I,CDROM.length());
+      unsigned long FileSize = 0;
+      
+      // Open the package file
+      FileFd Pkg;
+      if (FileExists(*I) == true)
+      {
+	 Pkg.Open(*I,FileFd::ReadOnly);
+	 FileSize = Pkg.Size();
+      }      
+      else
+      {
+	 FileFd From(*I + ".gz",FileFd::ReadOnly);
+	 if (_error->PendingError() == true)
+	    return false;
+	 FileSize = From.Size();
+	 
+	 // Get a temp file
+	 FILE *tmp = tmpfile();
+	 if (tmp == 0)
+	    return _error->Errno("tmpfile","Unable to create a tmp file");
+	 Pkg.Fd(dup(fileno(tmp)));
+	 fclose(tmp);
+	 
+	 // Fork gzip
+	 pid_t Process = fork();
+	 if (Process < 0)
+	    return _error->Errno("fork","Couldn't fork gzip");
+	 
+	 // The child
+	 if (Process == 0)
+	 {	    
+	    dup2(From.Fd(),STDIN_FILENO);
+	    dup2(Pkg.Fd(),STDOUT_FILENO);
+	    SetCloseExec(STDIN_FILENO,false);
+	    SetCloseExec(STDOUT_FILENO,false);
+	    
+	    const char *Args[3];
+	    string Tmp =  _config->Find("Dir::bin::gzip","gzip");
+	    Args[0] = Tmp.c_str();
+	    Args[1] = "-d";
+	    Args[2] = 0;
+	    execvp(Args[0],(char **)Args);
+	    exit(100);
+	 }
+	 
+	 // Wait for gzip to finish
+	 if (ExecWait(Process,_config->Find("Dir::bin::gzip","gzip").c_str(),false) == false)
+	    return _error->Error("gzip failed, perhaps the disk is full.");
+	 
+	 Pkg.Seek(0);
+      }
+      pkgTagFile Parser(&Pkg);
+      if (_error->PendingError() == true)
+	 return false;
+      
+      // Open the output file
+      char S[400];
+      snprintf(S,sizeof(S),"cdrom:[%s]/%s",Name.c_str(),
+	       (*I).c_str() + CDROM.length());
+      string TargetF = _config->FindDir("Dir::State::lists") + "partial/";
+      TargetF += URItoFileName(S);
+      if (_config->FindB("APT::CDROM::NoAct",false) == true)
+	 TargetF = "/dev/null";
+      FileFd Target(TargetF,FileFd::WriteEmpty);
+      FILE *TargetFl = fdopen(dup(Target.Fd()),"w");
+      if (_error->PendingError() == true)
+	 return false;
+      if (TargetFl == 0)
+	 return _error->Errno("fdopen","Failed to reopen fd");
+      
+      // Setup the progress meter
+      if(Progress)
+	 Progress->OverallProgress(CurrentSize,TotalSize,FileSize,
+				   string("Reading Translation Indexes"));
+
+      // Parse
+      if(Progress)
+	 Progress->SubProgress(Pkg.Size());
+      pkgTagSection Section;
+      this->Section = &Section;
+      string Prefix;
+      unsigned long Hits = 0;
+      unsigned long Chop = 0;
+      while (Parser.Step(Section) == true)
+      {
+	 if(Progress)
+	    Progress->Progress(Parser.Offset());
+
+	 const char *Start;
+	 const char *Stop;
+	 Section.GetSection(Start,Stop);
+	 fwrite(Start,Stop-Start, 1, TargetFl);
+	 fputc('\n',TargetFl);
+
+	 Packages++;
+	 Hits++;
+      }
+      fclose(TargetFl);
+
+      if (Debug == true)
+	 cout << " Processed by using Prefix '" << Prefix << "' and chop " << Chop << endl;
+	 
+      if (_config->FindB("APT::CDROM::NoAct",false) == false)
+      {
+	 // Move out of the partial directory
+	 Target.Close();
+	 string FinalF = _config->FindDir("Dir::State::lists");
+	 FinalF += URItoFileName(S);
+	 if (rename(TargetF.c_str(),FinalF.c_str()) != 0)
+	    return _error->Errno("rename","Failed to rename");
+      }
+      
+      
+      CurrentSize += FileSize;
+   }   
+   if(Progress)
+      Progress->Done();
+   
+   // Some stats
+   if(log) {
+      stringstream msg;
+      if(NotFound == 0 && WrongSize == 0)
+	 ioprintf(msg, _("Wrote %i records.\n"), Packages);
+      else if (NotFound != 0 && WrongSize == 0)
+	 ioprintf(msg, _("Wrote %i records with %i missing files.\n"), 
+		  Packages, NotFound);
+      else if (NotFound == 0 && WrongSize != 0)
+	 ioprintf(msg, _("Wrote %i records with %i mismatched files\n"), 
+		  Packages, WrongSize);
+      if (NotFound != 0 && WrongSize != 0)
+	 ioprintf(msg, _("Wrote %i records with %i missing files and %i mismatched files\n"), Packages, NotFound, WrongSize);
+   }
+   
+   if (Packages == 0)
+      _error->Warning("No valid records were found.");
+
+   if (NotFound + WrongSize > 10)
+      _error->Warning("Alot of entries were discarded, something may be wrong.\n");
+   
+
+   return true;
+}

+ 13 - 0
apt-pkg/indexcopy.h

@@ -70,6 +70,17 @@ class SourceCopy : public IndexCopy
    public:
 };
 
+class TranslationsCopy
+{
+   protected:
+   pkgTagSection *Section;
+
+   public:
+   bool CopyTranslations(string CDROM,string Name,vector<string> &List,
+			 pkgCdromStatus *log);
+};
+
+
 class SigVerify 
 {
    bool Verify(string prefix,string file, indexRecords *records);
@@ -81,4 +92,6 @@ class SigVerify
 		      vector<string> PkgList,vector<string> SrcList);
 };
 
+
+
 #endif