]> git.saurik.com Git - apt.git/blobdiff - cmdline/indexcopy.cc
Core correctness patches
[apt.git] / cmdline / indexcopy.cc
index 2585fc1da4be2f8eb22ce15a1adef52827294dd3..73d9e507714363e5e3a0b6d18a29426d167883ba 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: indexcopy.cc,v 1.2 1999/09/03 05:46:48 jgg Exp $
+// $Id: indexcopy.cc,v 1.7 2001/03/13 05:23:42 jgg Exp $
 /* ######################################################################
 
    Index Copying - Aid for copying and verifying the index files
@@ -23,7 +23,6 @@
 #include <unistd.h>
 #include <sys/stat.h>
 #include <stdio.h>
-#include <wait.h>
                                                                        /*}}}*/
 
 // IndexCopy::CopyPackages - Copy the package files from the CD                /*{{{*/
@@ -103,28 +102,29 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List)
         }
         
         // Wait for gzip to finish
-        int Status;
-        if (waitpid(Process,&Status,0) != Process)
-           return _error->Errno("wait","Waiting for gzip failed");
-        if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
+        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);
+      pkgTagFile Parser(&Pkg);
       if (_error->PendingError() == true)
         return false;
       
       // Open the output file
       char S[400];
-      sprintf(S,"cdrom:%s/%s%s",Name.c_str(),(*I).c_str() + CDROM.length(),
-             GetFileName());
+      snprintf(S,sizeof(S),"cdrom:[%s]/%s%s",Name.c_str(),
+              (*I).c_str() + CDROM.length(),GetFileName());
       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);      
+      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
       Progress.OverallProgress(CurrentSize,TotalSize,FileSize,
@@ -143,7 +143,10 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List)
         string File;
         unsigned long Size;
         if (GetFile(File,Size) == false)
+        {
+           fclose(TargetFl);
            return false;
+        }
         
         if (Chop != 0)
            File = OrigPath + ChopDirs(File,Chop);
@@ -205,21 +208,13 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List)
         Packages++;
         Hits++;
         
-        // Copy it to the target package file
-        if (Chop != 0 || Mangled == true)
+        if (RewriteEntry(TargetFl,File) == false)
         {
-           if (RewriteEntry(Target,File) == false)
-              continue;
+           fclose(TargetFl);
+           return false;
         }
-        else
-        {
-           const char *Start;
-           const char *Stop;
-           Section.GetSection(Start,Stop);
-           if (Target.Write(Start,Stop-Start) == false)
-              return false;
-        }       
       }
+      fclose(TargetFl);
 
       if (Debug == true)
         cout << " Processed by using Prefix '" << Prefix << "' and chop " << Chop << endl;
@@ -234,7 +229,8 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List)
            return _error->Errno("rename","Failed to rename");
 
         // Copy the release file
-        sprintf(S,"cdrom:%s/%sRelease",Name.c_str(),(*I).c_str() + CDROM.length());
+        snprintf(S,sizeof(S),"cdrom:[%s]/%sRelease",Name.c_str(),
+                 (*I).c_str() + CDROM.length());
         string TargetF = _config->FindDir("Dir::State::lists") + "partial/";
         TargetF += URItoFileName(S);
         if (FileExists(*I + "Release") == true)
@@ -371,11 +367,22 @@ bool IndexCopy::ReconstructChop(unsigned long &Chop,string Dir,string File)
 // ---------------------------------------------------------------------
 /* We look for things in dists/ notation and convert them to 
    <dist> <component> form otherwise it is left alone. This also strips
-   the CD path. */
+   the CD path. 
+   This implements a regex sort of like: 
+    (.*)/dists/([^/]*)/(.*)/binary-* 
+     ^          ^      ^- Component
+     |          |-------- Distribution
+     |------------------- Path
+   
+   It was deciced to use only a single word for dist (rather than say
+   unstable/non-us) to increase the chance that each CD gets a single
+   line in sources.list.
+ */
 void IndexCopy::ConvertToSourceList(string CD,string &Path)
 {
    char S[300];
-   sprintf(S,"binary-%s",_config->Find("Apt::Architecture").c_str());
+   snprintf(S,sizeof(S),"binary-%s",_config->Find("Apt::Architecture").c_str());
    
    // Strip the cdrom base path
    Path = string(Path,CD.length());
@@ -389,7 +396,7 @@ void IndexCopy::ConvertToSourceList(string CD,string &Path)
    // Not a dists type.
    if (stringcmp(Path.begin(),Path.begin()+strlen("dists/"),"dists/") != 0)
       return;
-
+      
    // Isolate the dist
    string::size_type Slash = strlen("dists/");
    string::size_type Slash2 = Path.find('/',Slash + 1);
@@ -398,21 +405,26 @@ void IndexCopy::ConvertToSourceList(string CD,string &Path)
    string Dist = string(Path,Slash,Slash2 - Slash);
    
    // Isolate the component
-   Slash = Path.find('/',Slash2+1);
-   if (Slash == string::npos || Slash + 2 >= Path.length())
-      return;
-   string Comp = string(Path,Slash2+1,Slash - Slash2-1);
-   
-   // Verify the trailing binar - bit
-   Slash2 = Path.find('/',Slash + 1);
-   if (Slash == string::npos)
-      return;
-   string Binary = string(Path,Slash+1,Slash2 - Slash-1);
-   
-   if (Binary != S && Binary != "source")
+   Slash = Slash2;
+   for (unsigned I = 0; I != 10; I++)
+   {
+      Slash = Path.find('/',Slash+1);
+      if (Slash == string::npos || Slash + 2 >= Path.length())
+        return;
+      string Comp = string(Path,Slash2+1,Slash - Slash2-1);
+        
+      // Verify the trailing binary- bit
+      string::size_type BinSlash = Path.find('/',Slash + 1);
+      if (Slash == string::npos)
+        return;
+      string Binary = string(Path,Slash+1,BinSlash - Slash-1);
+      
+      if (Binary != S && Binary != "source")
+        continue;
+
+      Path = Dist + ' ' + Comp;
       return;
-   
-   Path = Dist + ' ' + Comp;
+   }   
 }
                                                                        /*}}}*/
 // IndexCopy::GrabFirst - Return the first Depth path components       /*{{{*/
@@ -435,44 +447,6 @@ bool IndexCopy::GrabFirst(string Path,string &To,unsigned int Depth)
    return true;
 }
                                                                        /*}}}*/
-// IndexCopy::CopyWithReplace - Copy a section and replace text                /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool IndexCopy::CopyWithReplace(FileFd &Target,const char *Tag,string New)
-{
-   // Mangle the output filename
-   const char *Start;
-   const char *Stop;
-   const char *Filename;
-   Section->Find(Tag,Filename,Stop);
-   
-   /* We need to rewrite the filename field so we emit
-      all fields except the filename file and rewrite that one */
-   for (unsigned int I = 0; I != Section->Count(); I++)
-   {
-      Section->Get(Start,Stop,I);
-      if (Start <= Filename && Stop > Filename)
-      {
-        char S[500];
-        sprintf(S,"%s: %s\n",Tag,New.c_str());
-        if (I + 1 == Section->Count())
-           strcat(S,"\n");
-        if (Target.Write(S,strlen(S)) == false)
-           return false;
-      }
-      else
-      {
-        if (Target.Write(Start,Stop-Start) == false)
-           return false;
-        if (Stop[-1] != '\n')
-           if (Target.Write("\n",1) == false)
-              return false;
-      }               
-   }
-   if (Target.Write("\n",1) == false)
-      return false;
-}
-                                                                       /*}}}*/
 // PackageCopy::GetFile - Get the file information from the section    /*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -488,9 +462,15 @@ bool PackageCopy::GetFile(string &File,unsigned long &Size)
 // PackageCopy::RewriteEntry - Rewrite the entry with a new filename   /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-bool PackageCopy::RewriteEntry(FileFd &Target,string File)
+bool PackageCopy::RewriteEntry(FILE *Target,string File)
 {
-   return CopyWithReplace(Target,"Filename",File);
+   TFRewriteData Changes[] = {{"Filename",File.c_str()},
+                              {}};
+   
+   if (TFRewrite(Target,*Section,TFRewritePackageOrder,Changes) == false)
+      return false;
+   fputc('\n',Target);
+   return true;
 }
                                                                        /*}}}*/
 // SourceCopy::GetFile - Get the file information from the section     /*{{{*/
@@ -507,7 +487,7 @@ bool SourceCopy::GetFile(string &File,unsigned long &Size)
    if (Base.empty() == false && Base[Base.length()-1] != '/')
       Base += '/';
    
-   // Iterate over the entire list grabbing each triplet
+   // Read the first file triplet
    const char *C = Files.c_str();
    string sSize;
    string MD5Hash;
@@ -527,9 +507,15 @@ bool SourceCopy::GetFile(string &File,unsigned long &Size)
 // SourceCopy::RewriteEntry - Rewrite the entry with a new filename    /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-bool SourceCopy::RewriteEntry(FileFd &Target,string File)
+bool SourceCopy::RewriteEntry(FILE *Target,string File)
 {
-   return CopyWithReplace(Target,"Directory",
-                         string(File,0,File.rfind('/')));
+   string Dir(File,0,File.rfind('/'));
+   TFRewriteData Changes[] = {{"Directory",Dir.c_str()},
+                              {}};
+   
+   if (TFRewrite(Target,*Section,TFRewriteSourceOrder,Changes) == false)
+      return false;
+   fputc('\n',Target);
+   return true;
 }
                                                                        /*}}}*/