]> git.saurik.com Git - apt.git/blobdiff - apt-inst/extract.cc
centralize unlink checks in acquire-item
[apt.git] / apt-inst / extract.cc
index d184a5e9d6ddf1114d139791e3ff3290607df15a..026182c186ab5181f8dee410a85f8685abbf2da4 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: extract.cc,v 1.4 2002/03/26 07:38:57 jgg Exp $
+// $Id: extract.cc,v 1.6.2.1 2004/01/16 18:58:50 mdz Exp $
 /* ######################################################################
 
    Archive Extraction Directory Stream
@@ -10,7 +10,7 @@
    object is unpacked to '.dpkg.new' then the original is hardlinked to
    '.dpkg.tmp' and finally the new object is renamed to overwrite the old
    one. From an external perspective the file never ceased to exist.
-   After the archive has been sucessfully unpacked the .dpkg.tmp files 
+   After the archive has been successfully unpacked the .dpkg.tmp files
    are erased. A failure causes all the .dpkg.tmp files to be restored.
    
    Decisions about unpacking go like this:
@@ -22,7 +22,7 @@
         [Note, this is reduced to only check if a file was expected to be
          there]
       - If the existing link/file is not a directory then it is replaced
-        irregardless
+        regardless
       - If the existing link/directory is being replaced by a directory then
         absolutely nothing happens.
       - If the existing link/directory is being replaced by a link then
    ##################################################################### */
                                                                        /*}}}*/
 // Include Files                                                       /*{{{*/
-#ifdef __GNUG__
-#pragma implementation "apt-pkg/extract.h"
-#endif
+#include<config.h>
+
 #include <apt-pkg/extract.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/debversion.h>
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/dirstream.h>
+#include <apt-pkg/filelist.h>
+#include <apt-pkg/mmap.h>
+#include <apt-pkg/pkgcache.h>
+#include <apt-pkg/cacheiterators.h>
 
+#include <string.h>
+#include <string>
 #include <sys/stat.h>
 #include <stdio.h>
-#include <unistd.h>
 #include <errno.h>
 #include <dirent.h>
 #include <iostream>
+
+#include <apti18n.h>
                                                                        /*}}}*/
+using namespace std;
 
 static const char *TempExt = "dpkg-tmp";
 //static const char *NewExt = "dpkg-new";
@@ -77,10 +86,8 @@ pkgExtract::pkgExtract(pkgFLCache &FLCache,pkgCache::VerIterator Ver) :
 // Extract::DoItem - Handle a single item from the stream              /*{{{*/
 // ---------------------------------------------------------------------
 /* This performs the setup for the extraction.. */
-bool pkgExtract::DoItem(Item &Itm,int &Fd)
+bool pkgExtract::DoItem(Item &Itm, int &/*Fd*/)
 {
-   char Temp[sizeof(FileName)];
-   
    /* Strip any leading/trailing /s from the filename, then copy it to the
       temp buffer and re-apply the leading / We use a class variable
       to store the new filename for use by the three extraction funcs */
@@ -91,7 +98,7 @@ bool pkgExtract::DoItem(Item &Itm,int &Fd)
    for (; *I != 0 && End < FileName + sizeof(FileName); I++, End++)
       *End = *I;
    if (End + 20 >= FileName + sizeof(FileName))
-      return _error->Error("The path %s is too long",Itm.Name);   
+      return _error->Error(_("The path %s is too long"),Itm.Name);   
    for (; End > FileName && End[-1] == '/'; End--);
    *End = 0;
    Itm.Name = FileName;
@@ -122,7 +129,7 @@ bool pkgExtract::DoItem(Item &Itm,int &Fd)
       which case this needs to be modified anyhow.. */
    if ((RealNde->Flags & pkgFLCache::Node::Unpacked) ==
        pkgFLCache::Node::Unpacked)
-      return _error->Error("Unpacking %s more than once",Itm.Name);
+      return _error->Error(_("Unpacking %s more than once"),Itm.Name);
    
    if (Nde.end() == true)
       Nde = RealNde;
@@ -132,7 +139,7 @@ bool pkgExtract::DoItem(Item &Itm,int &Fd)
    if ((Nde->Flags & pkgFLCache::Node::Diversion) != 0)
    {
       if (Itm.Type == Item::Directory)
-        return _error->Error("The directory %s is diverted",Itm.Name);
+        return _error->Error(_("The directory %s is diverted"),Itm.Name);
 
       /* A package overwriting a diversion target is just the same as 
          overwriting a normally owned file and is checked for below in
@@ -142,8 +149,8 @@ bool pkgExtract::DoItem(Item &Itm,int &Fd)
          that is never, ever permitted */
       pkgFLCache::DiverIterator Div = Nde.Diversion();
       if (Div.DivertTo() == Nde)
-        return _error->Error("The package is trying to write to the "
-                             "diversion target %s/%s",Nde.DirN(),Nde.File());
+        return _error->Error(_("The package is trying to write to the "
+                             "diversion target %s/%s"),Nde.DirN(),Nde.File());
       
       // See if it is us and we are following it in the right direction
       if (Div->OwnerPkg != FLPkg.Offset() && Div.DivertFrom() == Nde)
@@ -152,7 +159,7 @@ bool pkgExtract::DoItem(Item &Itm,int &Fd)
         End = FileName + snprintf(FileName,sizeof(FileName)-20,"%s/%s",
                                   Nde.DirN(),Nde.File());
         if (End <= FileName)
-           return _error->Error("The diversion path is too long");
+           return _error->Error(_("The diversion path is too long"));
       }      
    }
    
@@ -162,7 +169,7 @@ bool pkgExtract::DoItem(Item &Itm,int &Fd)
    {
       string Res = flNoLink(Itm.Name);
       if (Res.length() > sizeof(FileName))
-        return _error->Error("The path %s is too long",Res.c_str());
+        return _error->Error(_("The path %s is too long"),Res.c_str());
       if (Debug == true)
         clog << "Followed conf file from " << FileName << " to " << Res << endl;
       Itm.Name = strcpy(FileName,Res.c_str());      
@@ -176,19 +183,20 @@ bool pkgExtract::DoItem(Item &Itm,int &Fd)
    {
       // This is bad news.
       if (errno != ENOENT)
-        return _error->Errno("stat","Failed to stat %s",Itm.Name);
+        return _error->Errno("stat",_("Failed to stat %s"),Itm.Name);
       
       // See if we can recover the backup file
       if (Nde.end() == false)
       {
+        char Temp[sizeof(FileName)];
         snprintf(Temp,sizeof(Temp),"%s.%s",Itm.Name,TempExt);
         if (rename(Temp,Itm.Name) != 0 && errno != ENOENT)
-           return _error->Errno("rename","Failed to rename %s to %s",
+           return _error->Errno("rename",_("Failed to rename %s to %s"),
                                 Temp,Itm.Name);
         if (stat(Itm.Name,&LExisting) != 0)
         {
            if (errno != ENOENT)
-              return _error->Errno("stat","Failed to stat %s",Itm.Name);
+              return _error->Errno("stat",_("Failed to stat %s"),Itm.Name);
         }       
         else
            EValid = true;
@@ -205,7 +213,7 @@ bool pkgExtract::DoItem(Item &Itm,int &Fd)
       if (stat(Itm.Name,&Existing) != 0)
       {
         if (errno != ENOENT)
-           return _error->Errno("stat","Failed to stat %s",Itm.Name);
+           return _error->Errno("stat",_("Failed to stat %s"),Itm.Name);
         Existing = LExisting;
       }      
    }
@@ -238,13 +246,13 @@ bool pkgExtract::DoItem(Item &Itm,int &Fd)
    if (S_ISDIR(Existing.st_mode) != 0)
    {
       if (CheckDirReplace(Itm.Name) == false)
-        return _error->Error("The directory %s is being replaced by a non-directory",Itm.Name);
+        return _error->Error(_("The directory %s is being replaced by a non-directory"),Itm.Name);
    }
    
    if (Debug == true)
       clog << "Extract " << string(Itm.Name,End) << endl;
 /*   if (Count != 0)
-      return _error->Error("Done");*/
+      return _error->Error(_("Done"));*/
    
    return true;
 }
@@ -252,7 +260,7 @@ bool pkgExtract::DoItem(Item &Itm,int &Fd)
 // Extract::Finished - Sequence finished, erase the temp files         /*{{{*/
 // ---------------------------------------------------------------------
 /* */
-bool pkgExtract::Finished()
+APT_CONST bool pkgExtract::Finished()
 {
    return true;
 }
@@ -278,11 +286,11 @@ bool pkgExtract::Aborted()
       pkgFLCache::NodeIterator Nde(FLCache,FLCache.HashNode(Files));
       for (; Nde.end() == false && Files->File != Nde->File; Nde++);
       if (Nde.end() == true)
-        return _error->Error("Failed to locate node in its hash bucket");
+        return _error->Error(_("Failed to locate node in its hash bucket"));
       
       if (snprintf(FileName,sizeof(FileName)-20,"%s/%s",
                   Nde.DirN(),Nde.File()) <= 0)
-        return _error->Error("The path is too long");
+        return _error->Error(_("The path is too long"));
       
       // Deal with diversions
       if ((Nde->Flags & pkgFLCache::Node::Diversion) != 0)
@@ -295,7 +303,7 @@ bool pkgExtract::Aborted()
            Nde = Div.DivertTo();
            if (snprintf(FileName,sizeof(FileName)-20,"%s/%s",
                         Nde.DirN(),Nde.File()) <= 0)
-              return _error->Error("The diversion path is too long");
+              return _error->Error(_("The diversion path is too long"));
         }
       }      
       
@@ -373,7 +381,6 @@ bool pkgExtract::HandleOverwrites(pkgFLCache::NodeIterator Nde,
    pkgFLCache::NodeIterator TmpNde = Nde;
    unsigned long DiverOwner = 0;
    unsigned long FileGroup = Nde->File;
-   const char *FirstOwner = 0;
    for (; Nde.end() == false && FileGroup == Nde->File; Nde++)
    {
       if ((Nde->Flags & pkgFLCache::Node::Diversion) != 0)
@@ -393,12 +400,11 @@ bool pkgExtract::HandleOverwrites(pkgFLCache::NodeIterator Nde,
          if something has already been diverted by this diversion */
       if (FPkg.Offset() == DiverOwner)
         continue;
-      FirstOwner = FPkg.Name();
-      
+
       // Now see if this package matches one in a replace depends
       pkgCache::DepIterator Dep = Ver.DependsList();
       bool Ok = false;
-      for (; Dep.end() == false; Dep++)
+      for (; Dep.end() == false; ++Dep)
       {
         if (Dep->Type != pkgCache::Dep::Replaces)
            continue;
@@ -412,7 +418,7 @@ bool pkgExtract::HandleOverwrites(pkgFLCache::NodeIterator Nde,
         pkgCache::PkgIterator Pkg = Dep.TargetPkg();
         if (Pkg->CurrentVer == 0)
         {
-           _error->Warning("Overwrite package match with no version for %s",Pkg.Name());
+           _error->Warning(_("Overwrite package match with no version for %s"),Pkg.Name());
            continue;
         }
 
@@ -429,7 +435,7 @@ bool pkgExtract::HandleOverwrites(pkgFLCache::NodeIterator Nde,
       
       // Negative Hit
       if (Ok == false)
-        return _error->Error("File %s/%s overwrites the one in the package %s",
+        return _error->Error(_("File %s/%s overwrites the one in the package %s"),
                              Nde.DirN(),Nde.File(),FPkg.Name());
    }
    
@@ -462,7 +468,7 @@ bool pkgExtract::CheckDirReplace(string Dir,unsigned int Depth)
    
    DIR *D = opendir(Dir.c_str());
    if (D == 0)
-      return _error->Errno("opendir","Unable to read %s",Dir.c_str());
+      return _error->Errno("opendir",_("Unable to read %s"),Dir.c_str());
 
    string File;
    for (struct dirent *Dent = readdir(D); Dent != 0; Dent = readdir(D))
@@ -489,7 +495,7 @@ bool pkgExtract::CheckDirReplace(string Dir,unsigned int Depth)
       if (lstat(File.c_str(),&St) != 0)
       {
         closedir(D);
-        return _error->Errno("lstat","Unable to stat %s",File.c_str());
+        return _error->Errno("lstat",_("Unable to stat %s"),File.c_str());
       }
       
       // Recurse down directories