Просмотр исходного кода

* merged with matt's tree

Patches applied:

 * apt@packages.debian.org/apt--main--0--patch-52
   0.6.31

 * apt@packages.debian.org/apt--main--0--patch-53
   Remove debugging from apt.cron.daily

 * apt@packages.debian.org/apt--main--0--patch-54
   allow SHA1Summation to process a file descriptor until EOF

 * apt@packages.debian.org/apt--main--0--patch-55
   Fix syntax in sha1.cc

 * apt@packages.debian.org/apt--main--0--patch-56
   Fix build/install of Polish offline documentation

 * apt@packages.debian.org/apt--main--0--patch-57
   Move CD-ROM handling backend into libapt-pkg

 * apt@packages.debian.org/apt--main--0--patch-58
   Fix compilation errors from apt--auth-cdrom--0

 * michael.vogt@ubuntu.com--2005/apt--auth-cdrom--0--base-0
   tag of apt@packages.debian.org/apt--main--0--patch-51

 * michael.vogt@ubuntu.com--2005/apt--auth-cdrom--0--patch-1
   * added support for signed cdroms 

 * michael.vogt@ubuntu.com--2005/apt--auth-cdrom--0--patch-2
   * merged with apt--main, seperated cmdline/apt-cdrom.cc into a library (apt-pkg/cdrom.{cc,h})

 * michael.vogt@ubuntu.com--2005/apt--auth-cdrom--0--patch-3
   * cleaned up the cmdline/apt-cdrom.cc code
Michael Vogt лет назад: 21
Родитель
Сommit
8501516a89

+ 776 - 0
apt-pkg/cdrom.cc

@@ -0,0 +1,776 @@
+/*
+ */
+
+#ifdef __GNUG__
+#pragma implementation "apt-pkg/cdrom.h"
+#endif
+#include<apt-pkg/init.h>
+#include<apt-pkg/error.h>
+#include<apt-pkg/cdromutl.h>
+#include<apt-pkg/strutl.h>
+#include<apt-pkg/cdrom.h>
+#include<sstream>
+#include<fstream>
+#include<config.h>
+#include<apti18n.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <stdio.h>
+
+
+#include "indexcopy.h"
+
+using namespace std;
+
+// FindPackages - Find the package files on the CDROM			/*{{{*/
+// ---------------------------------------------------------------------
+/* We look over the cdrom for package files. This is a recursive
+   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,
+			    string &InfoDir, pkgCdromStatus *log,
+			    unsigned int Depth)
+{
+   static ino_t Inodes[9];
+
+   // if we have a look we "pulse" now
+   if(log)
+      log->Update();
+
+   if (Depth >= 7)
+      return true;
+
+   if (CD[CD.length()-1] != '/')
+      CD += '/';   
+
+   if (chdir(CD.c_str()) != 0)
+      return _error->Errno("chdir","Unable to change to %s",CD.c_str());
+
+   // Look for a .disk subdirectory
+   struct stat Buf;
+   if (stat(".disk",&Buf) == 0)
+   {
+      if (InfoDir.empty() == true)
+	 InfoDir = CD + ".disk/";
+   }
+
+   // Don't look into directories that have been marked to ingore.
+   if (stat(".aptignr",&Buf) == 0)
+      return true;
+
+
+   /* Check _first_ for a signature file as apt-cdrom assumes that all files
+      under a Packages/Source file are in control of that file and stops 
+      the scanning
+   */
+   if (stat("Release.gpg",&Buf) == 0)
+   {
+      SigList.push_back(CD);
+   }
+   /* Aha! We found some package files. We assume that everything under 
+      this dir is controlled by those package files so we don't look down
+      anymore */
+   if (stat("Packages",&Buf) == 0 || stat("Packages.gz",&Buf) == 0)
+   {
+      List.push_back(CD);
+      
+      // Continue down if thorough is given
+      if (_config->FindB("APT::CDROM::Thorough",false) == false)
+	 return true;
+   }
+   if (stat("Sources.gz",&Buf) == 0 || stat("Sources",&Buf) == 0)
+   {
+      SList.push_back(CD);
+      
+      // Continue down if thorough is given
+      if (_config->FindB("APT::CDROM::Thorough",false) == false)
+	 return true;
+   }
+   
+   DIR *D = opendir(".");
+   if (D == 0)
+      return _error->Errno("opendir","Unable to read %s",CD.c_str());
+   
+   // Run over the directory
+   for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D))
+   {
+      // Skip some files..
+      if (strcmp(Dir->d_name,".") == 0 ||
+	  strcmp(Dir->d_name,"..") == 0 ||
+	  //strcmp(Dir->d_name,"source") == 0 ||
+	  strcmp(Dir->d_name,".disk") == 0 ||
+	  strcmp(Dir->d_name,"experimental") == 0 ||
+	  strcmp(Dir->d_name,"binary-all") == 0 ||
+          strcmp(Dir->d_name,"debian-installer") == 0)
+	 continue;
+
+      // See if the name is a sub directory
+      struct stat Buf;
+      if (stat(Dir->d_name,&Buf) != 0)
+	 continue;      
+      
+      if (S_ISDIR(Buf.st_mode) == 0)
+	 continue;
+      
+      unsigned int I;
+      for (I = 0; I != Depth; I++)
+	 if (Inodes[I] == Buf.st_ino)
+	    break;
+      if (I != Depth)
+	 continue;
+      
+      // Store the inodes weve seen
+      Inodes[Depth] = Buf.st_ino;
+
+      // Descend
+      if (FindPackages(CD + Dir->d_name,List,SList,SigList,InfoDir,log,Depth+1) == false)
+	 break;
+
+      if (chdir(CD.c_str()) != 0)
+	 return _error->Errno("chdir","Unable to change to %s",CD.c_str());
+   };
+
+   closedir(D);
+   
+   return !_error->PendingError();
+}
+
+// Score - We compute a 'score' for a path				/*{{{*/
+// ---------------------------------------------------------------------
+/* Paths are scored based on how close they come to what I consider
+   normal. That is ones that have 'dist' 'stable' 'testing' will score
+   higher than ones without. */
+int pkgCdrom::Score(string Path)
+{
+   int Res = 0;
+   if (Path.find("stable/") != string::npos)
+      Res += 29;
+   if (Path.find("/binary-") != string::npos)
+      Res += 20;
+   if (Path.find("testing/") != string::npos)
+      Res += 28;
+   if (Path.find("unstable/") != string::npos)
+      Res += 27;
+   if (Path.find("/dists/") != string::npos)
+      Res += 40;
+   if (Path.find("/main/") != string::npos)
+      Res += 20;
+   if (Path.find("/contrib/") != string::npos)
+      Res += 20;
+   if (Path.find("/non-free/") != string::npos)
+      Res += 20;
+   if (Path.find("/non-US/") != string::npos)
+      Res += 20;
+   if (Path.find("/source/") != string::npos)
+      Res += 10;
+   if (Path.find("/debian/") != string::npos)
+      Res -= 10;
+   return Res;
+}
+
+									/*}}}*/
+// DropBinaryArch - Dump dirs with a string like /binary-<foo>/		/*{{{*/
+// ---------------------------------------------------------------------
+/* Here we drop everything that is not this machines arch */
+bool pkgCdrom::DropBinaryArch(vector<string> &List)
+{
+   char S[300];
+   snprintf(S,sizeof(S),"/binary-%s/",
+	    _config->Find("Apt::Architecture").c_str());
+   
+   for (unsigned int I = 0; I < List.size(); I++)
+   {
+      const char *Str = List[I].c_str();
+      
+      const char *Res;
+      if ((Res = strstr(Str,"/binary-")) == 0)
+	 continue;
+
+      // Weird, remove it.
+      if (strlen(Res) < strlen(S))
+      {
+	 List.erase(List.begin() + I);
+	 I--;
+	 continue;
+      }
+	  
+      // See if it is our arch
+      if (stringcmp(Res,Res + strlen(S),S) == 0)
+	 continue;
+      
+      // Erase it
+      List.erase(List.begin() + I);
+      I--;
+   }
+   
+   return true;
+}
+
+
+// DropRepeats - Drop repeated files resulting from symlinks		/*{{{*/
+// ---------------------------------------------------------------------
+/* Here we go and stat every file that we found and strip dup inodes. */
+bool pkgCdrom::DropRepeats(vector<string> &List,const char *Name)
+{
+   // Get a list of all the inodes
+   ino_t *Inodes = new ino_t[List.size()];
+   for (unsigned int I = 0; I != List.size(); I++)
+   {
+      struct stat Buf;
+      if (stat((List[I] + Name).c_str(),&Buf) != 0 &&
+	  stat((List[I] + Name + ".gz").c_str(),&Buf) != 0)
+	 _error->Errno("stat","Failed to stat %s%s",List[I].c_str(),
+		       Name);
+      Inodes[I] = Buf.st_ino;
+   }
+   
+   if (_error->PendingError() == true)
+      return false;
+   
+   // Look for dups
+   for (unsigned int I = 0; I != List.size(); I++)
+   {
+      for (unsigned int J = I+1; J < List.size(); J++)
+      {
+	 // No match
+	 if (Inodes[J] != Inodes[I])
+	    continue;
+	 
+	 // We score the two paths.. and erase one
+	 int ScoreA = Score(List[I]);
+	 int ScoreB = Score(List[J]);
+	 if (ScoreA < ScoreB)
+	 {
+	    List[I] = string();
+	    break;
+	 }
+	 
+	 List[J] = string();
+      }
+   }  
+ 
+   // Wipe erased entries
+   for (unsigned int I = 0; I < List.size();)
+   {
+      if (List[I].empty() == false)
+	 I++;
+      else
+	 List.erase(List.begin()+I);
+   }
+   
+   return true;
+}
+									/*}}}*/
+
+// ReduceSourceList - Takes the path list and reduces it		/*{{{*/
+// ---------------------------------------------------------------------
+/* This takes the list of source list expressed entires and collects
+   similar ones to form a single entry for each dist */
+void pkgCdrom::ReduceSourcelist(string CD,vector<string> &List)
+{
+   sort(List.begin(),List.end());
+   
+   // Collect similar entries
+   for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
+   {
+      // Find a space..
+      string::size_type Space = (*I).find(' ');
+      if (Space == string::npos)
+	 continue;
+      string::size_type SSpace = (*I).find(' ',Space + 1);
+      if (SSpace == string::npos)
+	 continue;
+
+      string Word1 = string(*I,Space,SSpace-Space);
+      string Prefix = string(*I,0,Space);
+      for (vector<string>::iterator J = List.begin(); J != I; J++)
+      {
+	 // Find a space..
+	 string::size_type Space2 = (*J).find(' ');
+	 if (Space2 == string::npos)
+	    continue;
+	 string::size_type SSpace2 = (*J).find(' ',Space2 + 1);
+	 if (SSpace2 == string::npos)
+	    continue;
+	 
+	 if (string(*J,0,Space2) != Prefix)
+	    continue;
+	 if (string(*J,Space2,SSpace2-Space2) != Word1)
+	    continue;
+	 
+	 *J += string(*I,SSpace);
+	 *I = string();
+      }
+   }   
+
+   // Wipe erased entries
+   for (unsigned int I = 0; I < List.size();)
+   {
+      if (List[I].empty() == false)
+	 I++;
+      else
+	 List.erase(List.begin()+I);
+   }
+}
+									/*}}}*/
+// WriteDatabase - Write the CDROM Database file			/*{{{*/
+// ---------------------------------------------------------------------
+/* We rewrite the configuration class associated with the cdrom database. */
+bool pkgCdrom::WriteDatabase(Configuration &Cnf)
+{
+   string DFile = _config->FindFile("Dir::State::cdroms");
+   string NewFile = DFile + ".new";
+   
+   unlink(NewFile.c_str());
+   ofstream Out(NewFile.c_str());
+   if (!Out)
+      return _error->Errno("ofstream::ofstream",
+			   "Failed to open %s.new",DFile.c_str());
+   
+   /* Write out all of the configuration directives by walking the
+      configuration tree */
+   const Configuration::Item *Top = Cnf.Tree(0);
+   for (; Top != 0;)
+   {
+      // Print the config entry
+      if (Top->Value.empty() == false)
+	 Out <<  Top->FullTag() + " \"" << Top->Value << "\";" << endl;
+      
+      if (Top->Child != 0)
+      {
+	 Top = Top->Child;
+	 continue;
+      }
+      
+      while (Top != 0 && Top->Next == 0)
+	 Top = Top->Parent;
+      if (Top != 0)
+	 Top = Top->Next;
+   }   
+
+   Out.close();
+   
+   rename(DFile.c_str(),string(DFile + '~').c_str());
+   if (rename(NewFile.c_str(),DFile.c_str()) != 0)
+      return _error->Errno("rename","Failed to rename %s.new to %s",
+			   DFile.c_str(),DFile.c_str());
+
+   return true;
+}
+									/*}}}*/
+// WriteSourceList - Write an updated sourcelist			/*{{{*/
+// ---------------------------------------------------------------------
+/* This reads the old source list and copies it into the new one. It 
+   appends the new CDROM entires just after the first block of comments.
+   This places them first in the file. It also removes any old entries
+   that were the same. */
+bool pkgCdrom::WriteSourceList(string Name,vector<string> &List,bool Source)
+{
+   if (List.size() == 0)
+      return true;
+
+   string File = _config->FindFile("Dir::Etc::sourcelist");
+
+   // Open the stream for reading
+   ifstream F((FileExists(File)?File.c_str():"/dev/null"),
+	      ios::in );
+   if (!F != 0)
+      return _error->Errno("ifstream::ifstream","Opening %s",File.c_str());
+
+   string NewFile = File + ".new";
+   unlink(NewFile.c_str());
+   ofstream Out(NewFile.c_str());
+   if (!Out)
+      return _error->Errno("ofstream::ofstream",
+			   "Failed to open %s.new",File.c_str());
+
+   // Create a short uri without the path
+   string ShortURI = "cdrom:[" + Name + "]/";   
+   string ShortURI2 = "cdrom:" + Name + "/";     // For Compatibility
+
+   string Type;
+   if (Source == true)
+      Type = "deb-src";
+   else
+      Type = "deb";
+   
+   char Buffer[300];
+   int CurLine = 0;
+   bool First = true;
+   while (F.eof() == false)
+   {      
+      F.getline(Buffer,sizeof(Buffer));
+      CurLine++;
+      _strtabexpand(Buffer,sizeof(Buffer));
+      _strstrip(Buffer);
+            
+      // Comment or blank
+      if (Buffer[0] == '#' || Buffer[0] == 0)
+      {
+	 Out << Buffer << endl;
+	 continue;
+      }
+
+      if (First == true)
+      {
+	 for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
+	 {
+	    string::size_type Space = (*I).find(' ');
+	    if (Space == string::npos)
+	       return _error->Error("Internal error");
+	    Out << Type << " cdrom:[" << Name << "]/" << string(*I,0,Space) <<
+	       " " << string(*I,Space+1) << endl;
+	 }
+      }
+      First = false;
+      
+      // Grok it
+      string cType;
+      string URI;
+      const char *C = Buffer;
+      if (ParseQuoteWord(C,cType) == false ||
+	  ParseQuoteWord(C,URI) == false)
+      {
+	 Out << Buffer << endl;
+	 continue;
+      }
+
+      // Emit lines like this one
+      if (cType != Type || (string(URI,0,ShortURI.length()) != ShortURI &&
+	  string(URI,0,ShortURI.length()) != ShortURI2))
+      {
+	 Out << Buffer << endl;
+	 continue;
+      }      
+   }
+   
+   // Just in case the file was empty
+   if (First == true)
+   {
+      for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
+      {
+	 string::size_type Space = (*I).find(' ');
+	 if (Space == string::npos)
+	    return _error->Error("Internal error");
+	 
+	 Out << "deb cdrom:[" << Name << "]/" << string(*I,0,Space) << 
+	    " " << string(*I,Space+1) << endl;
+      }
+   }
+   
+   Out.close();
+
+   rename(File.c_str(),string(File + '~').c_str());
+   if (rename(NewFile.c_str(),File.c_str()) != 0)
+      return _error->Errno("rename","Failed to rename %s.new to %s",
+			   File.c_str(),File.c_str());
+   
+   return true;
+}
+
+
+bool pkgCdrom::Ident(string &ident, pkgCdromStatus *log)
+{
+   stringstream msg;
+
+   // Startup
+   string CDROM = _config->FindDir("Acquire::cdrom::mount","/cdrom/");
+   if (CDROM[0] == '.')
+      CDROM= SafeGetCWD() + '/' + CDROM;
+
+   if(log) {
+      msg.str("");
+      ioprintf(msg, _("Using CD-ROM mount point %s\nMounting CD-ROM\n"),
+		      CDROM.c_str());
+      log->Update(msg.str());
+   }
+   if (MountCdrom(CDROM) == false)
+      return _error->Error("Failed to mount the cdrom.");
+
+   // Hash the CD to get an ID
+   if(log) 
+      log->Update(_("Identifying.. "));
+   
+
+   if (IdentCdrom(CDROM,ident) == false)
+   {
+      ident = "";
+      return false;
+   }
+
+   msg.str("");
+   ioprintf(msg, "[%s]\n",ident.c_str());
+   log->Update(msg.str());
+
+
+   // Read the database
+   Configuration Database;
+   string DFile = _config->FindFile("Dir::State::cdroms");
+   if (FileExists(DFile) == true)
+   {
+      if (ReadConfigFile(Database,DFile) == false)
+	 return _error->Error("Unable to read the cdrom database %s",
+			      DFile.c_str());
+   }
+   if(log) {
+      msg.str("");
+      ioprintf(msg, _("Stored Label: %s \n"),
+	       Database.Find("CD::"+ident).c_str());
+      log->Update(msg.str());
+   }
+   return true;
+}
+
+
+bool pkgCdrom::Add(pkgCdromStatus *log)
+{
+   stringstream msg;
+
+   // Startup
+   string CDROM = _config->FindDir("Acquire::cdrom::mount","/cdrom/");
+   if (CDROM[0] == '.')
+      CDROM= SafeGetCWD() + '/' + CDROM;
+   
+   if(log) {
+      log->SetTotal(STEP_LAST);
+      msg.str("");
+      ioprintf(msg, _("Using CD-ROM mount point %s\n"), CDROM.c_str());
+      log->Update(msg.str(), STEP_PREPARE);
+   }
+
+   // Read the database
+   Configuration Database;
+   string DFile = _config->FindFile("Dir::State::cdroms");
+   if (FileExists(DFile) == true)
+   {
+      if (ReadConfigFile(Database,DFile) == false)
+	 return _error->Error("Unable to read the cdrom database %s",
+			      DFile.c_str());
+   }
+   
+   // Unmount the CD and get the user to put in the one they want
+   if (_config->FindB("APT::CDROM::NoMount",false) == false)
+   {
+      if(log)
+	 log->Update(_("Unmounting CD-ROM\n"), STEP_UNMOUNT);
+      UnmountCdrom(CDROM);
+
+      if(log) {
+	 log->Update(_("Waiting for disc...\n"), STEP_WAIT);
+	 if(!log->ChangeCdrom()) {
+	    // user aborted
+	    return false; 
+	 }
+      }
+
+      // Mount the new CDROM
+      log->Update(_("Mounting CD-ROM...\n"), STEP_MOUNT);
+      if (MountCdrom(CDROM) == false)
+	 return _error->Error("Failed to mount the cdrom.");
+   }
+   
+   // Hash the CD to get an ID
+   if(log)
+      log->Update(_("Identifying.. "), STEP_IDENT);
+   string ID;
+   if (IdentCdrom(CDROM,ID) == false)
+   {
+      log->Update("\n");
+      return false;
+   }
+   if(log) 
+      log->Update("["+ID+"]\n");
+
+   if(log) 
+      log->Update(_("Scanning Disc for index files..\n"),STEP_SCAN);
+   
+   // Get the CD structure
+   vector<string> List;
+   vector<string> SourceList;
+   vector<string> SigList;
+   string StartDir = SafeGetCWD();
+   string InfoDir;
+   if (FindPackages(CDROM,List,SourceList, SigList,InfoDir,log) == false)
+   {
+      log->Update("\n");
+      return false;
+   }
+
+   chdir(StartDir.c_str());
+
+   if (_config->FindB("Debug::aptcdrom",false) == true)
+   {
+      cout << "I found (binary):" << endl;
+      for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
+	 cout << *I << endl;
+      cout << "I found (source):" << endl;
+      for (vector<string>::iterator I = SourceList.begin(); I != SourceList.end(); I++)
+	 cout << *I << endl;
+      cout << "I found (Signatures):" << endl;
+      for (vector<string>::iterator I = SigList.begin(); I != SigList.end(); I++)
+	 cout << *I << endl;
+   }   
+
+   //log->Update(_("Cleaning package lists..."), STEP_CLEAN);
+
+   // Fix up the list
+   DropBinaryArch(List);
+   DropRepeats(List,"Packages");
+   DropRepeats(SourceList,"Sources");
+   DropRepeats(SigList,"Release.gpg");
+   if(log) {
+      msg.str("");
+      ioprintf(msg, _("Found %i package indexes, %i source indexes and "
+		      "%i signatures\n"), 
+	       List.size(), SourceList.size(), SigList.size());
+      log->Update(msg.str(), STEP_SCAN);
+   }
+
+   if (List.size() == 0 && SourceList.size() == 0)
+      return _error->Error("Unable to locate any package files, perhaps this is not a Debian Disc");
+
+   // Check if the CD is in the database
+   string Name;
+   if (Database.Exists("CD::" + ID) == false ||
+       _config->FindB("APT::CDROM::Rename",false) == true)
+   {
+      // Try to use the CDs label if at all possible
+      if (InfoDir.empty() == false &&
+	  FileExists(InfoDir + "/info") == true)
+      {
+	 ifstream F(string(InfoDir + "/info").c_str());
+	 if (!F == 0)
+	    getline(F,Name);
+
+	 if (Name.empty() == false)
+	 {
+	    // Escape special characters
+	    string::iterator J = Name.begin();
+	    for (; J != Name.end(); J++)
+	       if (*J == '"' || *J == ']' || *J == '[')
+		  *J = '_';
+	    
+	    if(log) {
+	       msg.str("");
+	       ioprintf(msg, "Found label '%s'\n", Name.c_str());
+	       log->Update(msg.str());
+	    }
+	    Database.Set("CD::" + ID + "::Label",Name);
+	 }	 
+      }
+      
+      if (_config->FindB("APT::CDROM::Rename",false) == true ||
+	  Name.empty() == true)
+      {
+	 if(!log) 
+	    return _error->Error("No disc name found and no way to ask for it");
+
+	 while(true) {
+	    if(!log->AskCdromName(Name)) {
+	       // user canceld
+	       return false; 
+	    }
+	    cout << "Name: '" << Name << "'" << endl;
+
+	    if (Name.empty() == false &&
+		Name.find('"') == string::npos &&
+		Name.find('[') == string::npos &&
+		Name.find(']') == string::npos)
+	       break;
+	    log->Update(_("That is not a valid name, try again.\n"));
+	 }
+      }      
+   }
+   else
+      Name = Database.Find("CD::" + ID);
+
+   // Escape special characters
+   string::iterator J = Name.begin();
+   for (; J != Name.end(); J++)
+      if (*J == '"' || *J == ']' || *J == '[')
+	 *J = '_';
+   
+   Database.Set("CD::" + ID,Name);
+   if(log) {
+      msg.str("");
+      ioprintf(msg, _("This Disc is called: \n'%s'\n"), Name.c_str());
+      log->Update(msg.str());
+   }
+
+   log->Update(_("Copying package lists..."), STEP_COPY);
+   // take care of the signatures and copy them if they are ok
+   // (we do this before PackageCopy as it modifies "List" and "SourceList")
+   SigVerify SignVerify;
+   SignVerify.CopyAndVerify(CDROM, Name, SigList, List, SourceList);
+   
+   // Copy the package files to the state directory
+   PackageCopy Copy;
+   SourceCopy SrcCopy;
+   if (Copy.CopyPackages(CDROM,Name,List, log) == false ||
+       SrcCopy.CopyPackages(CDROM,Name,SourceList, log) == false)
+      return false;
+
+   // reduce the List so that it takes less space in sources.list
+   ReduceSourcelist(CDROM,List);
+   ReduceSourcelist(CDROM,SourceList);
+
+   // Write the database and sourcelist
+   if (_config->FindB("APT::cdrom::NoAct",false) == false)
+   {
+      if (WriteDatabase(Database) == false)
+	 return false;
+      
+      if(log) {
+	 log->Update(_("Writing new source list\n"), STEP_WRITE);
+      }
+      if (WriteSourceList(Name,List,false) == false ||
+	  WriteSourceList(Name,SourceList,true) == false)
+	 return false;
+   }
+
+   // Print the sourcelist entries
+   if(log) 
+      log->Update(_("Source List entries for this Disc are:\n"));
+
+   for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
+   {
+      string::size_type Space = (*I).find(' ');
+      if (Space == string::npos)
+	 return _error->Error("Internal error");
+
+      if(log) {
+	 msg.str("");
+	 msg << "deb cdrom:[" << Name << "]/" << string(*I,0,Space) << 
+	    " " << string(*I,Space+1) << endl;
+	 log->Update(msg.str());
+      }
+   }
+
+   for (vector<string>::iterator I = SourceList.begin(); I != SourceList.end(); I++)
+   {
+      string::size_type Space = (*I).find(' ');
+      if (Space == string::npos)
+	 return _error->Error("Internal error");
+
+      if(log) {
+	 msg.str("");
+	 msg << "deb-src cdrom:[" << Name << "]/" << string(*I,0,Space) << 
+	    " " << string(*I,Space+1) << endl;
+	 log->Update(msg.str());
+      }
+   }
+
+   
+
+   // Unmount and finish
+   if (_config->FindB("APT::CDROM::NoMount",false) == false) {
+      log->Update(_("Unmounting CD-ROM..."), STEP_LAST);
+      UnmountCdrom(CDROM);
+   }
+
+   return true;
+}

+ 71 - 0
apt-pkg/cdrom.h

@@ -0,0 +1,71 @@
+#ifndef PKGLIB_CDROM_H
+#define PKGLIB_CDROM_H
+
+#include<apt-pkg/init.h>
+#include<string>
+#include<vector>
+
+#ifdef __GNUG__
+#pragma interface "apt-pkg/cdrom.h"
+#endif
+
+using namespace std;
+
+class pkgCdromStatus
+{
+ protected:
+   int totalSteps;
+
+ public:
+   pkgCdromStatus() {};
+   virtual ~pkgCdromStatus() {};
+
+   // total steps
+   virtual void SetTotal(int total) { totalSteps = total; };
+   // update steps, will be called regularly as a "pulse"
+   virtual void Update(string text="", int current=0) = 0;
+   
+   // ask for cdrom insert
+   virtual bool ChangeCdrom() = 0;
+   // ask for cdrom name
+   virtual bool AskCdromName(string &Name) = 0;
+   // Progress indicator for the Index rewriter
+   virtual OpProgress* GetOpProgress() {return NULL; };
+};
+
+class pkgCdrom 
+{
+ protected:
+   enum {
+      STEP_PREPARE = 1,
+      STEP_UNMOUNT,
+      STEP_WAIT,
+      STEP_MOUNT,
+      STEP_IDENT,
+      STEP_SCAN,
+      STEP_COPY,
+      STEP_WRITE,
+      STEP_UNMOUNT3,
+      STEP_LAST
+   };
+
+
+   bool FindPackages(string CD,vector<string> &List,
+		     vector<string> &SList, vector<string> &SigList,
+		     string &InfoDir, pkgCdromStatus *log,
+		     unsigned int Depth = 0);
+   bool DropBinaryArch(vector<string> &List);
+   bool DropRepeats(vector<string> &List,const char *Name);
+   void ReduceSourcelist(string CD,vector<string> &List);
+   bool WriteDatabase(Configuration &Cnf);
+   bool WriteSourceList(string Name,vector<string> &List,bool Source);
+   int Score(string Path);
+
+ public:
+   bool Ident(string &ident, pkgCdromStatus *log);
+   bool Add(pkgCdromStatus *log);
+};
+
+
+
+#endif

+ 8 - 3
apt-pkg/contrib/sha1.cc

@@ -343,11 +343,16 @@ bool SHA1Summation::AddFD(int Fd,unsigned long Size)
 {
    unsigned char Buf[64 * 64];
    int Res = 0;
-   while (Size != 0)
+   int ToEOF = (Size == 0);
+   while (Size != 0 || ToEOF)
    {
-      Res = read(Fd,Buf,MIN(Size,sizeof(Buf)));
-      if (Res < 0 || (unsigned) Res != MIN(Size,sizeof(Buf)))
+      unsigned n = sizeof(Buf);
+      if (!ToEOF) n = MIN(Size,n);
+      Res = read(Fd,Buf,n);
+      if (Res < 0 || (!ToEOF && (unsigned) Res != n)) // error, or short read
 	 return false;
+      if (ToEOF && Res == 0) // EOF
+         break;
       Size -= Res;
       Add(Buf,Res);
    }

+ 164 - 44
cmdline/indexcopy.cc

@@ -18,8 +18,13 @@
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/tagfile.h>
+#include <apt-pkg/indexrecords.h>
+#include <apt-pkg/md5.h>
+#include <apt-pkg/cdrom.h>
+#include <apti18n.h>
 
 #include <iostream>
+#include <sstream>
 #include <unistd.h>
 #include <sys/stat.h>
 #include <stdio.h>
@@ -30,12 +35,15 @@ using namespace std;
 // IndexCopy::CopyPackages - Copy the package files from the CD		/*{{{*/
 // ---------------------------------------------------------------------
 /* */
-bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List)
+bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
+			     pkgCdromStatus *log)
 {
+   OpProgress *Progress = NULL;
    if (List.size() == 0)
       return true;
    
-   OpTextProgress Progress;
+   if(log) 
+      Progress = log->GetOpProgress();
    
    bool NoStat = _config->FindB("APT::CDROM::Fast",false);
    bool Debug = _config->FindB("Debug::aptcdrom",false);
@@ -130,11 +138,13 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List)
 	 return _error->Errno("fdopen","Failed to reopen fd");
       
       // Setup the progress meter
-      Progress.OverallProgress(CurrentSize,TotalSize,FileSize,
-			       string("Reading ") + Type() + " Indexes");
+      if(Progress)
+	 Progress->OverallProgress(CurrentSize,TotalSize,FileSize,
+				   string("Reading ") + Type() + " Indexes");
 
       // Parse
-      Progress.SubProgress(Pkg.Size());
+      if(Progress)
+	 Progress->SubProgress(Pkg.Size());
       pkgTagSection Section;
       this->Section = &Section;
       string Prefix;
@@ -142,7 +152,8 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List)
       unsigned long Chop = 0;
       while (Parser.Step(Section) == true)
       {
-	 Progress.Progress(Parser.Offset());
+	 if(Progress)
+	    Progress->Progress(Parser.Offset());
 	 string File;
 	 unsigned long Size;
 	 if (GetFile(File,Size) == false)
@@ -230,35 +241,8 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List)
 	 FinalF += URItoFileName(S);
 	 if (rename(TargetF.c_str(),FinalF.c_str()) != 0)
 	    return _error->Errno("rename","Failed to rename");
-
-	 // Copy the release file
-	 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)
-	 {
-	    FileFd Target(TargetF,FileFd::WriteEmpty);
-	    FileFd Rel(*I + "Release",FileFd::ReadOnly);
-	    if (_error->PendingError() == true)
-	       return false;
-	    
-	    if (CopyFile(Rel,Target) == false)
-	       return false;
-	 }
-	 else
-	 {
-	    // Empty release file
-	    FileFd Target(TargetF,FileFd::WriteEmpty);	    
-	 }	 
-
-	 // Rename the release file
-	 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");
       }
-      
+	 
       /* Mangle the source to be in the proper notation with
        	 prefix dist [component] */ 
       *I = string(*I,Prefix.length());
@@ -267,23 +251,30 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List)
       
       CurrentSize += FileSize;
    }   
-   Progress.Done();
+   if(Progress)
+      Progress->Done();
    
    // Some stats
-   cout << "Wrote " << Packages << " records" ;
-   if (NotFound != 0)
-      cout << " with " << NotFound << " missing files";
-   if (NotFound != 0 && WrongSize != 0)
-      cout << " and"; 
-   if (WrongSize != 0)
-      cout << " with " << WrongSize << " mismatched files";
-   cout << '.' << endl;
+   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 mismachted files\n"), 
+		  Packages, WrongSize);
+      if (NotFound != 0 && WrongSize != 0)
+	 ioprintf(msg, _("Wrote %i records with %i missing files and %i mismachted files\n"), Packages, NotFound, WrongSize);
+   }
    
    if (Packages == 0)
       _error->Warning("No valid records were found.");
 
    if (NotFound + WrongSize > 10)
-      cout << "Alot of entries were discarded, something may be wrong." << endl;
+      _error->Warning("Alot of entries were discarded, something may be wrong.\n");
+   
 
    return true;
 }
@@ -521,4 +512,133 @@ bool SourceCopy::RewriteEntry(FILE *Target,string File)
    fputc('\n',Target);
    return true;
 }
+
+
 									/*}}}*/
+
+bool SigVerify::Verify(string prefix, string file, indexRecords *MetaIndex)
+{
+   const indexRecords::checkSum *Record = MetaIndex->Lookup(file);
+
+   if (!Record) 
+   {
+      _error->Warning("Can't find authentication record for: %s",file.c_str());
+      return false;
+   }
+
+   MD5Summation sum;
+   FileFd Fd(prefix+file, FileFd::ReadOnly);
+   sum.AddFD(Fd.Fd(), Fd.Size());
+   Fd.Close();
+   string MD5 = (string)sum.Result();
+   
+   if (Record->MD5Hash != MD5)
+   {
+      _error->Warning("MD5 mismatch for: %s",file.c_str());
+      return false;
+   }
+
+   if(_config->FindB("Debug::aptcdrom",false)) 
+   {
+      cout << "File: " << prefix+file << endl;
+      cout << "Expected MD5sum: " << Record->MD5Hash << endl;
+      cout << "got: " << MD5 << endl << endl;
+   }
+
+   return true;
+}
+
+bool SigVerify::CopyMetaIndex(string CDROM, string CDName, 
+			      string prefix, string file)
+{
+      char S[400];
+      snprintf(S,sizeof(S),"cdrom:[%s]/%s%s",CDName.c_str(),
+	       (prefix).c_str() + CDROM.length(),file.c_str());
+      string TargetF = _config->FindDir("Dir::State::lists");
+      TargetF += URItoFileName(S);
+
+      FileFd Target;
+      FileFd Rel;
+      Target.Open(TargetF,FileFd::WriteEmpty);
+      Rel.Open(prefix + file,FileFd::ReadOnly);
+      if (_error->PendingError() == true)
+	 return false;
+      if (CopyFile(Rel,Target) == false)
+	 return false;
+   
+      return true;
+}
+
+bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList,
+			      vector<string> PkgList,vector<string> SrcList)
+{
+   if (SigList.size() == 0)
+      return true;
+
+   bool Debug = _config->FindB("Debug::aptcdrom",false);
+
+   // Read all Release files
+   for (vector<string>::iterator I = SigList.begin(); I != SigList.end(); I++)
+   { 
+      if(Debug)
+	 cout << "Signature verify for: " << *I << endl;
+
+      indexRecords *MetaIndex = new indexRecords;
+      string prefix = *I; 
+
+      // a Release.gpg without a Release should never happen
+      if(!FileExists(*I+"Release"))
+	 continue;
+
+
+      // verify the gpg signature of "Release"
+      // gpg --verify "*I+Release.gpg", "*I+Release"
+      string gpgvpath = _config->Find("Dir::Bin::gpg", "/usr/bin/gpgv");
+      string pubringpath = _config->Find("Apt::GPGV::TrustedKeyring", "/etc/apt/trusted.gpg");
+      pid_t pid = ExecFork();
+      if(pid < 0) {
+	 _error->Error("Fork failed");
+	 return false;
+      }
+      if(pid == 0) {
+	 execlp(gpgvpath.c_str(), gpgvpath.c_str(), "--keyring", 
+		pubringpath.c_str(), string(*I+"Release.gpg").c_str(), 
+		string(*I+"Release").c_str(), NULL);
+      }
+      if(!ExecWait(pid, "gpgv")) {
+	 _error->Warning("Signature verification failed for: %s",
+			 string(*I+"Release.gpg").c_str());
+	 // something went wrong, don't copy the Release.gpg
+	 // FIXME: delete any existing gpg file?
+	 continue;
+      }
+
+      // Open the Release file and add it to the MetaIndex
+      if(!MetaIndex->Load(*I+"Release"))
+      {
+	 _error->Error(MetaIndex->ErrorText.c_str());
+	 return false;
+      }
+      
+      // go over the Indexfiles and see if they verify
+      // if so, remove them from our copy of the lists
+      vector<string> keys = MetaIndex->MetaKeys();
+      for (vector<string>::iterator I = keys.begin(); I != keys.end(); I++)
+      { 
+	 if(!Verify(prefix,*I, MetaIndex)) {
+	    // something went wrong, don't copy the Release.gpg
+	    // FIXME: delete any existing gpg file?
+	    continue;	 
+	 }
+      }
+
+      // we need a fresh one for the Release.gpg
+      delete MetaIndex;
+   
+      // everything was fine, copy the Release and Release.gpg file
+      CopyMetaIndex(CDROM, Name, prefix, "Release");
+      CopyMetaIndex(CDROM, Name, prefix, "Release.gpg");
+   }   
+
+   return true;
+}

+ 15 - 1
cmdline/indexcopy.h

@@ -19,6 +19,8 @@ using std::vector;
 
 class pkgTagSection;
 class FileFd;
+class indexRecords;
+class pkgCdromStatus;
 
 class IndexCopy
 {
@@ -39,7 +41,8 @@ class IndexCopy
    
    public:
 
-   bool CopyPackages(string CDROM,string Name,vector<string> &List);
+   bool CopyPackages(string CDROM,string Name,vector<string> &List,
+		     pkgCdromStatus *log);
 };
 
 class PackageCopy : public IndexCopy
@@ -66,4 +69,15 @@ class SourceCopy : public IndexCopy
    public:
 };
 
+class SigVerify 
+{
+   bool Verify(string prefix,string file, indexRecords *records);
+   bool CopyMetaIndex(string CDROM, string CDName, 
+		      string prefix, string file);
+
+ public:
+   bool CopyAndVerify(string CDROM,string Name,vector<string> &SigList,
+		      vector<string> PkgList,vector<string> SrcList);
+};
+
 #endif

+ 11 - 0
apt-pkg/indexrecords.cc

@@ -83,6 +83,17 @@ bool indexRecords::Load(const string Filename)
    return true;
 }
 
+vector<string> indexRecords::MetaKeys()
+{
+   std::vector<std::string> keys;
+   std::map<string,checkSum *>::iterator I = Entries.begin();
+   while(I != Entries.end()) {
+      keys.push_back((*I).first);
+      ++I;
+   }
+   return keys;
+}
+
 bool indexRecords::parseSumData(const char *&Start, const char *End,
 				   string &Name, string &Hash, size_t &Size)
 {

+ 3 - 1
apt-pkg/indexrecords.h

@@ -12,6 +12,7 @@
 #include <apt-pkg/fileutl.h>
 
 #include <map>
+#include <vector>
 
 class indexRecords
 {
@@ -34,7 +35,8 @@ class indexRecords
 
    // Lookup function
    virtual const checkSum *Lookup(const string MetaKey);
-   
+   std::vector<std::string> MetaKeys();
+
    virtual bool Load(string Filename);
    string GetDist() const;
    virtual bool CheckDist(const string MaybeDist) const;

+ 3 - 3
apt-pkg/makefile

@@ -13,7 +13,7 @@ include ../buildlib/defaults.mak
 # methods/makefile - FIXME
 LIBRARY=apt-pkg
 LIBEXT=$(GLIBC_VER)$(LIBSTDCPP_VER)
-MAJOR=3.8
+MAJOR=3.9
 MINOR=0
 SLIBS=$(PTHREADLIB) $(INTLLIBS)
 APT_DOMAIN:=libapt-pkg$(MAJOR)
@@ -34,14 +34,14 @@ SOURCE+= pkgcache.cc version.cc depcache.cc \
 	 acquire-worker.cc acquire-method.cc init.cc clean.cc \
 	 srcrecords.cc cachefile.cc versionmatch.cc policy.cc \
 	 pkgsystem.cc indexfile.cc pkgcachegen.cc acquire-item.cc \
-	 indexrecords.cc vendor.cc vendorlist.cc
+	 indexrecords.cc vendor.cc vendorlist.cc cdrom.cc indexcopy.cc
 HEADERS+= algorithms.h depcache.h pkgcachegen.h cacheiterators.h \
 	  orderlist.h sourcelist.h packagemanager.h tagfile.h \
 	  init.h pkgcache.h version.h progress.h pkgrecords.h \
 	  acquire.h acquire-worker.h acquire-item.h acquire-method.h \
 	  clean.h srcrecords.h cachefile.h versionmatch.h policy.h \
 	  pkgsystem.h indexfile.h metaindex.h indexrecords.h vendor.h \
-          vendorlist.h
+          vendorlist.h cdrom.h indexcopy.h
 
 # Source code for the debian specific components
 # In theory the deb headers do not need to be exported..

+ 56 - 649
cmdline/apt-cdrom.cc

@@ -18,10 +18,13 @@
 #include <apt-pkg/progress.h>
 #include <apt-pkg/cdromutl.h>
 #include <apt-pkg/strutl.h>
+#include <apt-pkg/acquire.h>
+#include <apt-pkg/acquire-item.h>
+#include <apt-pkg/cdrom.h>
 #include <config.h>
 #include <apti18n.h>
     
-#include "indexcopy.h"
+//#include "indexcopy.h"
 
 #include <locale.h>
 #include <iostream>
@@ -37,460 +40,65 @@
 
 using namespace std;
 
-// FindPackages - Find the package files on the CDROM			/*{{{*/
-// ---------------------------------------------------------------------
-/* We look over the cdrom for package files. This is a recursive
-   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 FindPackages(string CD,vector<string> &List,vector<string> &SList,
-		  string &InfoDir,unsigned int Depth = 0)
+                                                                        /*{{{*/
+class pkgCdromTextStatus : public pkgCdromStatus
 {
-   static ino_t Inodes[9];
-   if (Depth >= 7)
-      return true;
-
-   if (CD[CD.length()-1] != '/')
-      CD += '/';   
-
-   if (chdir(CD.c_str()) != 0)
-      return _error->Errno("chdir","Unable to change to %s",CD.c_str());
-
-   // Look for a .disk subdirectory
-   struct stat Buf;
-   if (stat(".disk",&Buf) == 0)
-   {
-      if (InfoDir.empty() == true)
-	 InfoDir = CD + ".disk/";
-   }
-
-   // Don't look into directories that have been marked to ingore.
-   if (stat(".aptignr",&Buf) == 0)
-      return true;
-   
-   /* Aha! We found some package files. We assume that everything under 
-      this dir is controlled by those package files so we don't look down
-      anymore */
-   if (stat("Packages",&Buf) == 0 || stat("Packages.gz",&Buf) == 0)
-   {
-      List.push_back(CD);
-      
-      // Continue down if thorough is given
-      if (_config->FindB("APT::CDROM::Thorough",false) == false)
-	 return true;
-   }
-   if (stat("Sources.gz",&Buf) == 0 || stat("Sources",&Buf) == 0)
-   {
-      SList.push_back(CD);
-      
-      // Continue down if thorough is given
-      if (_config->FindB("APT::CDROM::Thorough",false) == false)
-	 return true;
-   }
-   
-   DIR *D = opendir(".");
-   if (D == 0)
-      return _error->Errno("opendir","Unable to read %s",CD.c_str());
-   
-   // Run over the directory
-   for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D))
-   {
-      // Skip some files..
-      if (strcmp(Dir->d_name,".") == 0 ||
-	  strcmp(Dir->d_name,"..") == 0 ||
-	  //strcmp(Dir->d_name,"source") == 0 ||
-	  strcmp(Dir->d_name,".disk") == 0 ||
-	  strcmp(Dir->d_name,"experimental") == 0 ||
-	  strcmp(Dir->d_name,"binary-all") == 0 ||
-          strcmp(Dir->d_name,"debian-installer") == 0)
-	 continue;
-
-      // See if the name is a sub directory
-      struct stat Buf;
-      if (stat(Dir->d_name,&Buf) != 0)
-	 continue;      
-      
-      if (S_ISDIR(Buf.st_mode) == 0)
-	 continue;
-      
-      unsigned int I;
-      for (I = 0; I != Depth; I++)
-	 if (Inodes[I] == Buf.st_ino)
-	    break;
-      if (I != Depth)
-	 continue;
-      
-      // Store the inodes weve seen
-      Inodes[Depth] = Buf.st_ino;
-
-      // Descend
-      if (FindPackages(CD + Dir->d_name,List,SList,InfoDir,Depth+1) == false)
-	 break;
-
-      if (chdir(CD.c_str()) != 0)
-	 return _error->Errno("chdir","Unable to change to %s",CD.c_str());
-   };
-
-   closedir(D);
-   
-   return !_error->PendingError();
-}
-									/*}}}*/
-// DropBinaryArch - Dump dirs with a string like /binary-<foo>/		/*{{{*/
-// ---------------------------------------------------------------------
-/* Here we drop everything that is not this machines arch */
-bool DropBinaryArch(vector<string> &List)
+protected:
+   OpTextProgress Progress;
+   void Prompt(const char *Text); 
+   string PromptLine(const char *Text);
+   bool AskCdromName(string &name);
+
+public:
+   virtual void Update(string text, int current);
+   virtual bool ChangeCdrom();
+   virtual OpProgress* GetOpProgress();
+};
+
+void pkgCdromTextStatus::Prompt(const char *Text) 
 {
-   char S[300];
-   snprintf(S,sizeof(S),"/binary-%s/",
-	    _config->Find("Apt::Architecture").c_str());
-   
-   for (unsigned int I = 0; I < List.size(); I++)
-   {
-      const char *Str = List[I].c_str();
-      
-      const char *Res;
-      if ((Res = strstr(Str,"/binary-")) == 0)
-	 continue;
-
-      // Weird, remove it.
-      if (strlen(Res) < strlen(S))
-      {
-	 List.erase(List.begin() + I);
-	 I--;
-	 continue;
-      }
-	  
-      // See if it is our arch
-      if (stringcmp(Res,Res + strlen(S),S) == 0)
-	 continue;
-      
-      // Erase it
-      List.erase(List.begin() + I);
-      I--;
-   }
-   
-   return true;
+   char C;
+   cout << Text << ' ' << flush;
+   read(STDIN_FILENO,&C,1);
+   if (C != '\n')
+      cout << endl;
 }
-									/*}}}*/
-// Score - We compute a 'score' for a path				/*{{{*/
-// ---------------------------------------------------------------------
-/* Paths are scored based on how close they come to what I consider
-   normal. That is ones that have 'dist' 'stable' 'testing' will score
-   higher than ones without. */
-int Score(string Path)
+
+string pkgCdromTextStatus::PromptLine(const char *Text)
 {
-   int Res = 0;
-   if (Path.find("stable/") != string::npos)
-      Res += 29;
-   if (Path.find("/binary-") != string::npos)
-      Res += 20;
-   if (Path.find("testing/") != string::npos)
-      Res += 28;
-   if (Path.find("unstable/") != string::npos)
-      Res += 27;
-   if (Path.find("/dists/") != string::npos)
-      Res += 40;
-   if (Path.find("/main/") != string::npos)
-      Res += 20;
-   if (Path.find("/contrib/") != string::npos)
-      Res += 20;
-   if (Path.find("/non-free/") != string::npos)
-      Res += 20;
-   if (Path.find("/non-US/") != string::npos)
-      Res += 20;
-   if (Path.find("/source/") != string::npos)
-      Res += 10;
-   if (Path.find("/debian/") != string::npos)
-      Res -= 10;
+   cout << Text << ':' << endl;
+   
+   string Res;
+   getline(cin,Res);
    return Res;
 }
-									/*}}}*/
-// DropRepeats - Drop repeated files resulting from symlinks		/*{{{*/
-// ---------------------------------------------------------------------
-/* Here we go and stat every file that we found and strip dup inodes. */
-bool DropRepeats(vector<string> &List,const char *Name)
+
+bool pkgCdromTextStatus::AskCdromName(string &name) 
 {
-   // Get a list of all the inodes
-   ino_t *Inodes = new ino_t[List.size()];
-   for (unsigned int I = 0; I != List.size(); I++)
-   {
-      struct stat Buf;
-      if (stat((List[I] + Name).c_str(),&Buf) != 0 &&
-	  stat((List[I] + Name + ".gz").c_str(),&Buf) != 0)
-	 _error->Errno("stat","Failed to stat %s%s",List[I].c_str(),
-		       Name);
-      Inodes[I] = Buf.st_ino;
-   }
-   
-   if (_error->PendingError() == true)
-      return false;
-   
-   // Look for dups
-   for (unsigned int I = 0; I != List.size(); I++)
-   {
-      for (unsigned int J = I+1; J < List.size(); J++)
-      {
-	 // No match
-	 if (Inodes[J] != Inodes[I])
-	    continue;
-	 
-	 // We score the two paths.. and erase one
-	 int ScoreA = Score(List[I]);
-	 int ScoreB = Score(List[J]);
-	 if (ScoreA < ScoreB)
-	 {
-	    List[I] = string();
-	    break;
-	 }
+   cout << "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" << flush;
+   name = PromptLine("");
 	 
-	 List[J] = string();
-      }
-   }  
- 
-   // Wipe erased entries
-   for (unsigned int I = 0; I < List.size();)
-   {
-      if (List[I].empty() == false)
-	 I++;
-      else
-	 List.erase(List.begin()+I);
-   }
-   
    return true;
 }
-									/*}}}*/
-
-// ReduceSourceList - Takes the path list and reduces it		/*{{{*/
-// ---------------------------------------------------------------------
-/* This takes the list of source list expressed entires and collects
-   similar ones to form a single entry for each dist */
-void ReduceSourcelist(string CD,vector<string> &List)
-{
-   sort(List.begin(),List.end());
    
-   // Collect similar entries
-   for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
-   {
-      // Find a space..
-      string::size_type Space = (*I).find(' ');
-      if (Space == string::npos)
-	 continue;
-      string::size_type SSpace = (*I).find(' ',Space + 1);
-      if (SSpace == string::npos)
-	 continue;
 
-      string Word1 = string(*I,Space,SSpace-Space);
-      string Prefix = string(*I,0,Space);
-      for (vector<string>::iterator J = List.begin(); J != I; J++)
-      {
-	 // Find a space..
-	 string::size_type Space2 = (*J).find(' ');
-	 if (Space2 == string::npos)
-	    continue;
-	 string::size_type SSpace2 = (*J).find(' ',Space2 + 1);
-	 if (SSpace2 == string::npos)
-	    continue;
-	 
-	 if (string(*J,0,Space2) != Prefix)
-	    continue;
-	 if (string(*J,Space2,SSpace2-Space2) != Word1)
-	    continue;
-	 
-	 *J += string(*I,SSpace);
-	 *I = string();
-      }
-   }   
-
-   // Wipe erased entries
-   for (unsigned int I = 0; I < List.size();)
-   {
-      if (List[I].empty() == false)
-	 I++;
-      else
-	 List.erase(List.begin()+I);
-   }
-}
-									/*}}}*/
-// WriteDatabase - Write the CDROM Database file			/*{{{*/
-// ---------------------------------------------------------------------
-/* We rewrite the configuration class associated with the cdrom database. */
-bool WriteDatabase(Configuration &Cnf)
+void pkgCdromTextStatus::Update(string text, int current) 
 {
-   string DFile = _config->FindFile("Dir::State::cdroms");
-   string NewFile = DFile + ".new";
-   
-   unlink(NewFile.c_str());
-   ofstream Out(NewFile.c_str());
-   if (!Out)
-      return _error->Errno("ofstream::ofstream",
-			   "Failed to open %s.new",DFile.c_str());
-   
-   /* Write out all of the configuration directives by walking the
-      configuration tree */
-   const Configuration::Item *Top = Cnf.Tree(0);
-   for (; Top != 0;)
-   {
-      // Print the config entry
-      if (Top->Value.empty() == false)
-	 Out <<  Top->FullTag() + " \"" << Top->Value << "\";" << endl;
-      
-      if (Top->Child != 0)
-      {
-	 Top = Top->Child;
-	 continue;
-      }
-      
-      while (Top != 0 && Top->Next == 0)
-	 Top = Top->Parent;
-      if (Top != 0)
-	 Top = Top->Next;
-   }   
-
-   Out.close();
-   
-   rename(DFile.c_str(),string(DFile + '~').c_str());
-   if (rename(NewFile.c_str(),DFile.c_str()) != 0)
-      return _error->Errno("rename","Failed to rename %s.new to %s",
-			   DFile.c_str(),DFile.c_str());
-
-   return true;
+   if(text.size() > 0)
+      cout << text << flush;
 }
-									/*}}}*/
-// WriteSourceList - Write an updated sourcelist			/*{{{*/
-// ---------------------------------------------------------------------
-/* This reads the old source list and copies it into the new one. It 
-   appends the new CDROM entires just after the first block of comments.
-   This places them first in the file. It also removes any old entries
-   that were the same. */
-bool WriteSourceList(string Name,vector<string> &List,bool Source)
-{
-   if (List.size() == 0)
-      return true;
-
-   string File = _config->FindFile("Dir::Etc::sourcelist");
-
-   // Open the stream for reading
-   ifstream F((FileExists(File)?File.c_str():"/dev/null"),
-	      ios::in );
-   if (!F != 0)
-      return _error->Errno("ifstream::ifstream","Opening %s",File.c_str());
-
-   string NewFile = File + ".new";
-   unlink(NewFile.c_str());
-   ofstream Out(NewFile.c_str());
-   if (!Out)
-      return _error->Errno("ofstream::ofstream",
-			   "Failed to open %s.new",File.c_str());
 
-   // Create a short uri without the path
-   string ShortURI = "cdrom:[" + Name + "]/";   
-   string ShortURI2 = "cdrom:" + Name + "/";     // For Compatibility
-
-   const char *Type;
-   if (Source == true)
-      Type = "deb-src";
-   else
-      Type = "deb";
-   
-   char Buffer[300];
-   int CurLine = 0;
-   bool First = true;
-   while (F.eof() == false)
-   {      
-      F.getline(Buffer,sizeof(Buffer));
-      CurLine++;
-      _strtabexpand(Buffer,sizeof(Buffer));
-      _strstrip(Buffer);
-            
-      // Comment or blank
-      if (Buffer[0] == '#' || Buffer[0] == 0)
-      {
-	 Out << Buffer << endl;
-	 continue;
-      }
-
-      if (First == true)
-      {
-	 for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
-	 {
-	    string::size_type Space = (*I).find(' ');
-	    if (Space == string::npos)
-	       return _error->Error("Internal error");
-	    Out << Type << " cdrom:[" << Name << "]/" << string(*I,0,Space) <<
-	       " " << string(*I,Space+1) << endl;
-	 }
-      }
-      First = false;
-      
-      // Grok it
-      string cType;
-      string URI;
-      const char *C = Buffer;
-      if (ParseQuoteWord(C,cType) == false ||
-	  ParseQuoteWord(C,URI) == false)
-      {
-	 Out << Buffer << endl;
-	 continue;
-      }
-
-      // Emit lines like this one
-      if (cType != Type || (string(URI,0,ShortURI.length()) != ShortURI &&
-	  string(URI,0,ShortURI.length()) != ShortURI2))
-      {
-	 Out << Buffer << endl;
-	 continue;
-      }      
-   }
-   
-   // Just in case the file was empty
-   if (First == true)
-   {
-      for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
-      {
-	 string::size_type Space = (*I).find(' ');
-	 if (Space == string::npos)
-	    return _error->Error("Internal error");
-	 
-	 Out << "deb cdrom:[" << Name << "]/" << string(*I,0,Space) << 
-	    " " << string(*I,Space+1) << endl;
-      }
-   }
-   
-   Out.close();
-
-   rename(File.c_str(),string(File + '~').c_str());
-   if (rename(NewFile.c_str(),File.c_str()) != 0)
-      return _error->Errno("rename","Failed to rename %s.new to %s",
-			   File.c_str(),File.c_str());
-   
+bool pkgCdromTextStatus::ChangeCdrom() 
+{
+   Prompt("Please insert a Disc in the drive and press enter");
    return true;
 }
-									/*}}}*/
 
-// Prompt - Simple prompt						/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void Prompt(const char *Text)
-{
-   char C;
-   cout << Text << ' ' << flush;
-   read(STDIN_FILENO,&C,1);
-   if (C != '\n')
-      cout << endl;
-}
-									/*}}}*/
-// PromptLine - Prompt for an input line				/*{{{*/
-// ---------------------------------------------------------------------
-/* */
-string PromptLine(const char *Text)
-{
-   cout << Text << ':' << endl;
-   
-   string Res;
-   getline(cin,Res);
-   return Res;
-}
+OpProgress* pkgCdromTextStatus::GetOpProgress() 
+{ 
+   return &Progress; 
+};
+
 									/*}}}*/
 
 // DoAdd - Add a new CDROM						/*{{{*/
@@ -501,186 +109,13 @@ string PromptLine(const char *Text)
    verify them. Then rewrite the database files */
 bool DoAdd(CommandLine &)
 {
-   // Startup
-   string CDROM = _config->FindDir("Acquire::cdrom::mount","/cdrom/");
-   if (CDROM[0] == '.')
-      CDROM= SafeGetCWD() + '/' + CDROM;
-   
-   cout << "Using CD-ROM mount point " << CDROM << endl;
-      
-   // Read the database
-   Configuration Database;
-   string DFile = _config->FindFile("Dir::State::cdroms");
-   if (FileExists(DFile) == true)
-   {
-      if (ReadConfigFile(Database,DFile) == false)
-	 return _error->Error("Unable to read the cdrom database %s",
-			      DFile.c_str());
-   }
-   
-   // Unmount the CD and get the user to put in the one they want
-   if (_config->FindB("APT::CDROM::NoMount",false) == false)
-   {
-      cout << "Unmounting CD-ROM" << endl;
-      UnmountCdrom(CDROM);
-
-      // Mount the new CDROM
-      Prompt("Please insert a Disc in the drive and press enter");
-      cout << "Mounting CD-ROM" << endl;
-      if (MountCdrom(CDROM) == false)
-	 return _error->Error("Failed to mount the cdrom.");
-   }
-   
-   // Hash the CD to get an ID
-   cout << "Identifying.. " << flush;
-   string ID;
-   if (IdentCdrom(CDROM,ID) == false)
-   {
-      cout << endl;
-      return false;
-   }
-   
-   cout << '[' << ID << ']' << endl;
-
-   cout << "Scanning Disc for index files..  " << flush;
-   // Get the CD structure
-   vector<string> List;
-   vector<string> sList;
-   string StartDir = SafeGetCWD();
-   string InfoDir;
-   if (FindPackages(CDROM,List,sList,InfoDir) == false)
-   {
-      cout << endl;
-      return false;
-   }
-   
-   chdir(StartDir.c_str());
-
-   if (_config->FindB("Debug::aptcdrom",false) == true)
-   {
-      cout << "I found (binary):" << endl;
-      for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
-	 cout << *I << endl;
-      cout << "I found (source):" << endl;
-      for (vector<string>::iterator I = sList.begin(); I != sList.end(); I++)
-	 cout << *I << endl;
-   }   
-   
-   // Fix up the list
-   DropBinaryArch(List);
-   DropRepeats(List,"Packages");
-   DropRepeats(sList,"Sources");
-   cout << "Found " << List.size() << " package indexes and " << sList.size() << 
-      " source indexes." << endl;
-
-   if (List.size() == 0 && sList.size() == 0)
-      return _error->Error("Unable to locate any package files, perhaps this is not a Debian Disc");
-   
-   // Check if the CD is in the database
-   string Name;
-   if (Database.Exists("CD::" + ID) == false ||
-       _config->FindB("APT::CDROM::Rename",false) == true)
-   {
-      // Try to use the CDs label if at all possible
-      if (InfoDir.empty() == false &&
-	  FileExists(InfoDir + "/info") == true)
-      {
-	 ifstream F(string(InfoDir + "/info").c_str());
-	 if (!F == 0)
-	    getline(F,Name);
-
-	 if (Name.empty() == false)
-	 {
-	    // Escape special characters
-	    string::iterator J = Name.begin();
-	    for (; J != Name.end(); J++)
-	       if (*J == '"' || *J == ']' || *J == '[')
-		  *J = '_';
-	    
-	    cout << "Found label '" << Name << "'" << endl;
-	    Database.Set("CD::" + ID + "::Label",Name);
-	 }	 
-      }
-      
-      if (_config->FindB("APT::CDROM::Rename",false) == true ||
-	  Name.empty() == true)
-      {
-	 cout << "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'";
-	 while (1)
-	 {
-	    Name = PromptLine("");
-	    if (Name.empty() == false &&
-		Name.find('"') == string::npos &&
-		Name.find('[') == string::npos &&
-		Name.find(']') == string::npos)
-	       break;
-	    cout << "That is not a valid name, try again " << endl;
-	 }	 
-      }      
-   }
-   else
-      Name = Database.Find("CD::" + ID);
-
-   // Escape special characters
-   string::iterator J = Name.begin();
-   for (; J != Name.end(); J++)
-      if (*J == '"' || *J == ']' || *J == '[')
-	 *J = '_';
-   
-   Database.Set("CD::" + ID,Name);
-   cout << "This Disc is called:" << endl << " '" << Name << "'" << endl;
-   
-   // Copy the package files to the state directory
-   PackageCopy Copy;
-   SourceCopy SrcCopy;
-   if (Copy.CopyPackages(CDROM,Name,List) == false ||
-       SrcCopy.CopyPackages(CDROM,Name,sList) == false)
-      return false;
-   
-   ReduceSourcelist(CDROM,List);
-   ReduceSourcelist(CDROM,sList);
-
-   // Write the database and sourcelist
-   if (_config->FindB("APT::cdrom::NoAct",false) == false)
-   {
-      if (WriteDatabase(Database) == false)
-	 return false;
-      
-      cout << "Writing new source list" << endl;
-      if (WriteSourceList(Name,List,false) == false ||
-	  WriteSourceList(Name,sList,true) == false)
-	 return false;
-   }
-
-   // Print the sourcelist entries
-   cout << "Source List entries for this Disc are:" << endl;
-   for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
-   {
-      string::size_type Space = (*I).find(' ');
-      if (Space == string::npos)
-	 return _error->Error("Internal error");
-
-      cout << "deb cdrom:[" << Name << "]/" << string(*I,0,Space) << 
-	 " " << string(*I,Space+1) << endl;
-   }
-
-   for (vector<string>::iterator I = sList.begin(); I != sList.end(); I++)
-   {
-      string::size_type Space = (*I).find(' ');
-      if (Space == string::npos)
-	 return _error->Error("Internal error");
-
-      cout << "deb-src cdrom:[" << Name << "]/" << string(*I,0,Space) << 
-	 " " << string(*I,Space+1) << endl;
-   }
-
-   cout << "Repeat this process for the rest of the CDs in your set." << endl;
-
-   // Unmount and finish
-   if (_config->FindB("APT::CDROM::NoMount",false) == false)
-      UnmountCdrom(CDROM);
-   
-   return true;
+   bool res = false;
+   pkgCdromTextStatus log;
+   pkgCdrom cdrom;
+   res = cdrom.Add(&log);
+   if(res)
+      cout << "Repeat this process for the rest of the CDs in your set." << endl;
+   return res;
 }
 									/*}}}*/
 // DoIdent - Ident a CDROM						/*{{{*/
@@ -688,38 +123,10 @@ bool DoAdd(CommandLine &)
 /* */
 bool DoIdent(CommandLine &)
 {
-   // Startup
-   string CDROM = _config->FindDir("Acquire::cdrom::mount","/cdrom/");
-   if (CDROM[0] == '.')
-      CDROM= SafeGetCWD() + '/' + CDROM;
-   
-   cout << "Using CD-ROM mount point " << CDROM << endl;
-   cout << "Mounting CD-ROM" << endl;
-   if (MountCdrom(CDROM) == false)
-      return _error->Error("Failed to mount the cdrom.");
-   
-   // Hash the CD to get an ID
-   cout << "Identifying.. " << flush;
-   string ID;
-   if (IdentCdrom(CDROM,ID) == false)
-   {
-      cout << endl;
-      return false;
-   }
-   
-   cout << '[' << ID << ']' << endl;
-
-   // Read the database
-   Configuration Database;
-   string DFile = _config->FindFile("Dir::State::cdroms");
-   if (FileExists(DFile) == true)
-   {
-      if (ReadConfigFile(Database,DFile) == false)
-	 return _error->Error("Unable to read the cdrom database %s",
-			      DFile.c_str());
-   }
-   cout << "Stored Label: '" << Database.Find("CD::" + ID) << "'" << endl;
-   return true;
+   string ident;
+   pkgCdromTextStatus log;
+   pkgCdrom cdrom;
+   return cdrom.Ident(ident, &log);
 }
 									/*}}}*/
 

+ 1 - 1
cmdline/makefile

@@ -30,7 +30,7 @@ include $(PROGRAM_H)
 PROGRAM=apt-cdrom
 SLIBS = -lapt-pkg
 LIB_MAKES = apt-pkg/makefile
-SOURCE = apt-cdrom.cc indexcopy.cc
+SOURCE = apt-cdrom.cc 
 include $(PROGRAM_H)
 
 # The apt-sortpkgs program

+ 1 - 1
configure.in

@@ -18,7 +18,7 @@ AC_CONFIG_AUX_DIR(buildlib)
 AC_CONFIG_HEADER(include/config.h:buildlib/config.h.in include/apti18n.h:buildlib/apti18n.h.in)
 
 dnl -- SET THIS TO THE RELEASE VERSION --
-AC_DEFINE_UNQUOTED(VERSION,"0.6.30")
+AC_DEFINE_UNQUOTED(VERSION,"0.6.31")
 PACKAGE="apt"
 AC_DEFINE_UNQUOTED(PACKAGE,"$PACKAGE")
 AC_SUBST(PACKAGE)

+ 0 - 1
debian/apt.cron.daily

@@ -20,7 +20,6 @@ check_stamp()
     stamp=$(date --date=$(date -r $stamp --iso-8601) +%s)
     now=$(date --date=$(date --iso-8601) +%s)
     delta=$(($now-$stamp))
-    echo "stamp=$stamp, now=$now, delta=$delta"
 
     if [ $delta -ge $interval ]; then
         return 0

+ 15 - 0
debian/changelog

@@ -1,3 +1,18 @@
+apt (0.6.31) hoary; urgency=low
+
+  * Matt Zimmerman
+    - Remove debugging output from apt.cron.daily (no one noticed?)
+    - Apply patch from Anthony Towns to allow SHA1Summation to process a file
+      descriptor until EOF, rather than requiring that the length of input be
+      specified (Closes: #291338)
+    - Fix build/install of Polish offline documentation, based on patch from
+      Christian Perrier (Closes: #270404)
+  * Michael Vogt
+    - apt-cdrom.cc seperated into frontend (cmdline/apt-cdrom.cc and library
+      apt-pkg/cdrom.{cc,h}) (Ubuntu #5668)
+
+ -- Matt Zimmerman <mdz@ubuntu.com>  Fri,  4 Feb 2005 10:23:01 -0800
+
 apt (0.6.30) unstable; urgency=low
 
   * Add ppc64 to buildlib/archtable

+ 2 - 2
debian/rules

@@ -36,7 +36,7 @@ endif
 # Default rule
 build:
 
-DEB_BUILD_PROG:=debuild --preserve-envvar PATH --preserve-envvar CCACHE_DIR -us -uc $(DEBUILD_DPKG_BUILDPACKAGE_OPTS)
+DEB_BUILD_PROG:=debuild --preserve-envvar PATH --preserve-envvar CCACHE_DIR -us -uc $(DEB_BUILD_PROG_OPTS)
 APT_DEBVER=$(shell dpkg-parsechangelog |sed -n -e '/^Version:/s/^Version: //p')
 APT_CONFVER=$(shell sed -n -e 's/^AC_DEFINE_UNQUOTED(VERSION,"\(.*\)")/\1/p' configure.in)
 APT_CVSTAG=$(shell echo "$(APT_DEBVER)" | sed -e 's/^/v/' -e 's/\./_/g')
@@ -171,7 +171,7 @@ apt-doc: build-doc
 #
 	# Copy the guides
 	dh_installdocs -p$@ $(BLD)/docs/guide*.text $(BLD)/docs/guide*.html \
-	               $(BLD)/docs/offline.text $(BLD)/docs/offline.html
+	               $(BLD)/docs/offline*.text $(BLD)/docs/offline*.html
 	dh_installchangelogs -p$@
 	dh_compress -p$@
 	dh_fixperms -p$@

+ 90 - 90
doc/pl/offline.pl.sgml

@@ -1,80 +1,80 @@
 <!doctype debiandoc system>
 <!-- -*- mode: sgml; mode: fold -*- -->
 <book>
-<title>Używanie APT w trybie offline</title>
+<title>U�ywanie APT w trybie offline</title>
 
 <author>Jason Gunthorpe <email>jgg@debian.org</email></author>
-<author>Polskie tłumaczenie Krzysztof Fiertek <email>akfedux@megapolis.pl</email></author>
+<author>Polskie t�umaczenie Krzysztof Fiertek <email>akfedux@megapolis.pl</email></author>
 <version>$Id: offline.pl.sgml,v 1.1 2004/07/29 16:43:13 mdz Exp $</version>
 
 <abstract>
-Dokument ten opisuje jak używać programu APT w środowiskach niesieciowych,
-a w szczególności metodę pozwalającą na robienie aktualizacji systemu.
+Dokument ten opisuje jak u�ywa� programu APT w �rodowiskach niesieciowych,
+a w szczeg�lno�ci metod� pozwalaj�c� na robienie aktualizacji systemu.
 </abstract>
 
 <copyright>
 Copyright &copy; Jason Gunthorpe, 1999.
 <p>
-Copyright &copy; polskiego tłumaczenia Krzysztof Fiertek, 2004.
+Copyright &copy; polskiego t�umaczenia Krzysztof Fiertek, 2004.
 <p>
-"APT" i ten dokument są oprogramowaniem wolnodostępnym; możesz
-rozpowszechniać je i/lub zmieniać w zgodzie z postanowieniami
-"Ogólnej Licencji Publicznej GNU" (GNU General Public License)
-takiej, jak została opublikowana przez "Fundacje Wolnego
-Oprogramowania (Free Software Foundation); albo w wersji 2 tejże
-licencji, albo (twój wybór) w dowolnej późniejszej.
+"APT" i ten dokument s� oprogramowaniem wolnodost�pnym; mo�esz
+rozpowszechniaďż˝ je i/lub zmieniaďż˝ w zgodzie z postanowieniami
+"Og�lnej Licencji Publicznej GNU" (GNU General Public License)
+takiej, jak zosta�a opublikowana przez "Fundacje Wolnego
+Oprogramowania (Free Software Foundation); albo w wersji 2 tej�e
+licencji, albo (tw�j wyb�r) w dowolnej p��niejszej.
 
 <p>
-Więcej szczegółów możesz uzyskać przeglądając plik zawierający pełny tekst
+Wi�cej szczeg���w mo�esz uzyska� przegl�daj�c plik zawieraj�cy pe�ny tekst
 licencji (w systemach Debian jest to plik /usr/doc/copyright/GPL).
 </copyright
 
 <toc sect>
 
-<chapt>Wstęp
+<chapt>Wst�p
 <!-- Overview                                                         {{{ -->
 <!-- ===================================================================== -->
 <sect>Wprowadzenie
 
 <p>
-Normalnie APT wymaga bezpośredniego dostępu do archiwów Debiana poprzez
-sieć lokalną albo przez sieć internetową. Kolejną niedogodnością może być
-fakt, że nasz komputer, który pracuje na wolnym łączu takim jak modem,
-jest znacznie oddalony od innnego komputera z szybkim łączem.
+Normalnie APT wymaga bezpo�redniego dost�pu do archiw�w Debiana poprzez
+sie� lokaln� albo przez sie� internetow�. Kolejn� niedogodno�ci� mo�e by�
+fakt, �e nasz komputer, kt�ry pracuje na wolnym ��czu takim jak modem,
+jest znacznie oddalony od innnego komputera z szybkim ��czem.
 
 <p>
-Rozwiązaniem tego problemu jest użycie pojemnych przenośnych nośników
-takich jak dyskietka Zip lub dysk SuperDisk. Nośniki te nie są
-wystarczająco pojemne, by zgromadzić kompletne archiwum Debiana, ale można
-śmiało dopasować podzbiór dużego archiwum wystarczający dla większości
-użytkowników. Pomysł polega na tym, by użyć programu APT do wygenerowania
-listy pakietów, które są wymagane, następnie pobraniu ich na dysk używając
-innego komputera z właściwą zwartością. Jest nawet możliwe, by użyć innego
-komputera z Debianem z zainstalowanym programem APT lub zupełnie innym
-systemem operacyjnym i programem narzędziowym do pobierania plików takim
+Rozwi�zaniem tego problemu jest u�ycie pojemnych przeno�nych no�nik�w
+takich jak dyskietka Zip lub dysk SuperDisk. No�niki te nie s�
+wystarczaj�co pojemne, by zgromadzi� kompletne archiwum Debiana, ale mo�na
+�mia�o dopasowa� podzbi�r du�ego archiwum wystarczaj�cy dla wi�kszo�ci
+u�ytkownik�w. Pomys� polega na tym, by u�y� programu APT do wygenerowania
+listy pakiet�w, kt�re s� wymagane, nast�pnie pobraniu ich na dysk u�ywaj�c
+innego komputera z w�a�ciw� zwarto�ci�. Jest nawet mo�liwe, by u�y� innego
+komputera z Debianem z zainstalowanym programem APT lub zupe�nie innym
+systemem operacyjnym i programem narz�dziowym do pobierania plik�w takim
 jak wget.
 
 <p>
-Osiągnięte jest to przez twórcze manipulowanie plikiem konfiguracyjnym
-programu APT. Rzeczą niezbędną jest poinformowanie programu APT, aby wskazywał
-na dysk z plikami archiwum. Należy zauważyć, że dysk powinien być
-sformatowany do obsługi systemu plików takiego jak ext2, fat32 albo vfat
-pozwalających posługiwać się długimi nazwami pliku.
+Osi�gni�te jest to przez tw�rcze manipulowanie plikiem konfiguracyjnym
+programu APT. Rzecz� niezb�dn� jest poinformowanie programu APT, aby wskazywa�
+na dysk z plikami archiwum. Nale�y zauwa�y�, �e dysk powinien by�
+sformatowany do obs�ugi systemu plik�w takiego jak ext2, fat32 albo vfat
+pozwalaj�cych pos�ugiwa� si� d�ugimi nazwami pliku.
 
 </sect>
                                                                   <!-- }}} -->
 
-<chapt>Używanie programu APT na obu komputerach
+<chapt>U�ywanie programu APT na obu komputerach
 <!-- Overview                                                         {{{ -->
 <!-- ===================================================================== -->
 <sect>Wprowadzenie
 
 <p>
-APT będący do dyspozycji na obu komputerach daje najprostszą kombinację.
-Zasadniczym pomysłem tej metody jest umieścić kopie pliku status na dysku
-i użyć odległego komputera, aby uzyskać najnowsze pliki pakietów
-i zdecydować, które pakiety chcemy pobrać. Struktura katalogów na dysku
-powinna wyglądać następująco:
+APT b�d�cy do dyspozycji na obu komputerach daje najprostsz� kombinacj�.
+Zasadniczym pomys�em tej metody jest umie�ci� kopie pliku status na dysku
+i u�y� odleg�ego komputera, aby uzyska� najnowsze pliki pakiet�w
+i zdecydowa�, kt�re pakiety chcemy pobra�. Struktura katalog�w na dysku
+powinna wygl�da� nast�puj�co:
 
 <example>
   /disc/
@@ -94,21 +94,21 @@ powinna wygl
 <sect>Plik konfiguracyjny
 
 <p>
-Plik konfiguracyjny powinien informować program APT, aby przechowywać jego
-pliki na dysku, a także używać plików konfiguracyjnych z dysku. Plik
-sources.list powinien zawierać prawidłowe odnośniki, których oczekujesz
-użyć od zdalnego komputera, a plik status powinien być kopią 
-<em>/var/lib/dpkg/status</em>. Zauważ, że jeśli używasz lokalnego archiwum 
-musisz użyć tych samych odnośników o identycznej składni.
+Plik konfiguracyjny powinien informowaďż˝ program APT, aby przechowywaďż˝ jego
+pliki na dysku, a tak�e u�ywa� plik�w konfiguracyjnych z dysku. Plik
+sources.list powinien zawiera� prawid�owe odno�niki, kt�rych oczekujesz
+u�y� od zdalnego komputera, a plik status powinien by� kopi� 
+<em>/var/lib/dpkg/status</em>. Zauwa�, �e je�li u�ywasz lokalnego archiwum 
+musisz u�y� tych samych odno�nik�w o identycznej sk�adni.
 
 <p>
-<em>apt.conf</em> musi zawierać niezbędne wpisy, by APT korzystał z dysku:
+<em>apt.conf</em> musi zawiera� niezb�dne wpisy, by APT korzysta� z dysku:
 
 <example>
  APT
  {
-   /* Ten wpis nie jest wymagany jeśli oba komputery są tej samej
-      architektury, mówi on APTowi na komputerze pobierającym pakiety
+   /* Ten wpis nie jest wymagany je�li oba komputery s� tej samej
+      architektury, m�wi on APTowi na komputerze pobieraj�cym pakiety
       jakiej architektury jest nasz komputer */
    Architecture "i386";
    
@@ -117,12 +117,12 @@ musisz u
  
  Dir
  {
-   /* Użyj katalogu disc na informacje stanu i skieruj plik status
+   /* U�yj katalogu disc na informacje stanu i skieruj plik status
       z /var/lib/dpkg default */
    State "/disc/";
    State::status "status";
 
-   // Katalog lokalnie przechowywanych pakietów binarnych
+   // Katalog lokalnie przechowywanych pakiet�w binarnych
    Cache::archives "/disc/archives/";
    Cache "/tmp/";
 
@@ -131,15 +131,15 @@ musisz u
  }; 
 </example>
 
-Więcej szczegółów można zobaczyć w manualu apt.conf i w przykładowym pliku
+Wi�cej szczeg���w mo�na zobaczy� w manualu apt.conf i w przyk�adowym pliku
 konfiguracyjnym <em>/usr/doc/apt/examples/apt.conf</em>.
 
 <p>
-Pierwszą rzeczą jaka należy zrobić na oddalonym komputerze z Debianem to
-zamontować dysk i przekopiować na niego plik <em>/var/lib/dpkg/status</em>.
-Potrzeba także utworzyć stukturę katalogów przedstawioną we Wprowadzeniu,
-<em>archives/partial/</em> i <em>lists/partial/</em>. Następnie niesiemy
-dysk do oddalonego komputera z szybkim łączem i konfigurujemy plik
+Pierwsz� rzecz� jaka nale�y zrobi� na oddalonym komputerze z Debianem to
+zamontowaďż˝ dysk i przekopiowaďż˝ na niego plik <em>/var/lib/dpkg/status</em>.
+Potrzeba tak�e utworzy� stuktur� katalog�w przedstawion� we Wprowadzeniu,
+<em>archives/partial/</em> i <em>lists/partial/</em>. Nast�pnie niesiemy
+dysk do oddalonego komputera z szybkim ��czem i konfigurujemy plik
 sources.list. Na oddalonym komputerze wykonujemy kolejno:
 
 <example>
@@ -151,54 +151,54 @@ sources.list. Na oddalonym komputerze wykonujemy kolejno:
 
 </example>
 
-Polecenie dist-upgrade można zastąpić każdym innym podstawowym poleceniem
-APT, w szczególności dselect-upgrade. Możesz nawet użyć APT jako metodę
-dostępu dla <em>dselect</em>. Jednak stworzy to problem w przeniesieniu
-twoich operacji wyborów z powrotem na lokalny komputer.
+Polecenie dist-upgrade mo�na zast�pi� ka�dym innym podstawowym poleceniem
+APT, w szczeg�lno�ci dselect-upgrade. Mo�esz nawet u�y� APT jako metod�
+dost�pu dla <em>dselect</em>. Jednak stworzy to problem w przeniesieniu
+twoich operacji wybor�w z powrotem na lokalny komputer.
 
 <p>
 W tej chwili katalog disc zawiera wszystkie pliki indeksowe oraz archiwa
-niezbędne do aktualizacji maszyny z Debianem. Bierzemy dysk z powrotem do
+niezb�dne do aktualizacji maszyny z Debianem. Bierzemy dysk z powrotem do
 siebie i wpisujemy:
 
 <example>
   # export APT_CONFIG="/disc/apt.conf"
   # apt-get check
-  [ APT tworzy lokalną kopię plików cache ]
+  [ APT tworzy lokaln� kopi� plik�w cache ]
   # apt-get --no-d -o dir::etc::status=/var/lib/dpkg/status dist-upgrade
-  [ Może też być inne polecenie programu APT ]
+  [ Mo�e te� by� inne polecenie programu APT ]
 </example>
 
 <p> 
-Koniecznym jest do prawidłowego działania podmienić plik status na lokalnej
-maszynie. To jest bardzo ważne!
+Koniecznym jest do prawid�owego dzia�ania podmieni� plik status na lokalnej
+maszynie. To jest bardzo wa�ne!
 
 <p>
-Jeśli używasz dselect możesz wykonać bardzo ryzykowną operację skopiowania
-disc/status do /var/lib/dpkg/status tak, że  wszystkie zmiany które
-dokonałeś na odległym komputerze są uaktualnione. Mocno zalecam aby
-dokonywać doboru pakietów tylko na lokalnym komputerze, ale nie zawsze
-jest to możliwe. NIE podmieniaj pliku status jeśli dpkg lub APT były
-uruchamiane w międzyczasie!!
+Je�li u�ywasz dselect mo�esz wykona� bardzo ryzykown� operacj� skopiowania
+disc/status do /var/lib/dpkg/status tak, �e  wszystkie zmiany kt�re
+dokona�e� na odleg�ym komputerze s� uaktualnione. Mocno zalecam aby
+dokonywa� doboru pakiet�w tylko na lokalnym komputerze, ale nie zawsze
+jest to mo�liwe. NIE podmieniaj pliku status je�li dpkg lub APT by�y
+uruchamiane w mi�dzyczasie!!
 
 </sect>
                                                                   <!-- }}} -->
 
-<chapt>Używanie programów APT i wget
+<chapt>U�ywanie program�w APT i wget
 <!-- Overview                                                         {{{ -->
 <!-- ===================================================================== -->
 <sect>Wprowadzenie
 
 <p>
-<em>wget</em> jest popularnym i przenośnym programem narzędziowym
-pobierania plików, który działa na prawie każdym komputerze.
-W przeciwieństwie do metody opisanej powyżej ta wymaga komputera z Debianem,
-który już posiada listę dostępnych pakietów.
+<em>wget</em> jest popularnym i przeno�nym programem narz�dziowym
+pobierania plik�w, kt�ry dzia�a na prawie ka�dym komputerze.
+W przeciwie�stwie do metody opisanej powy�ej ta wymaga komputera z Debianem,
+kt�ry ju� posiada list� dost�pnych pakiet�w.
 
 <p>
-Należy stworzyć katalog disc tylko na pakiety do pobrania z innego
-komputera. Użyta zostanie do tego opcja --print-uris programu apt-get,
-a następnie przygotujemy skrypt dla programu wget, który pobierze właściwe
+Nale�y stworzy� katalog disc tylko na pakiety do pobrania z innego
+komputera. U�yta zostanie do tego opcja --print-uris programu apt-get,
+a nast�pnie przygotujemy skrypt dla programu wget, kt�ry pobierze w�a�ciwe
 pakiety.
 
 </sect>
@@ -208,28 +208,28 @@ pakiety.
 <sect>Kolejne kroki
 
 <p>
-W odróżnieniu od poprzedniej metody działania ta nie wymaga specjalnych
-plików konfiguracyjnych. Używamy jedynie podstawowych poleceń APT, by
-wygenerować listę plików.
+W odr��nieniu od poprzedniej metody dzia�ania ta nie wymaga specjalnych
+plik�w konfiguracyjnych. U�ywamy jedynie podstawowych polece� APT, by
+wygenerowa� list� plik�w.
 
 <example>
  # apt-get dist-upgrade 
- [ Wybierz no po znaku zachęty, upewnij się czy to właściwy wybór ]
+ [ Wybierz no po znaku zach�ty, upewnij si� czy to w�a?ciwy wyb�r ]
  # apt-get -qq --print-uris dist-upgrade > uris
  # awk '{print "wget -O " $2 " " $1}' < uris > /disc/wget-script
 </example>
 
-Także inne opcje niż dist-upgrade mogą tu być użyte, włączając
+Tak�e inne opcje ni� dist-upgrade mog� tu by� u�yte, w��czaj�c
 dselect-upgrade.
 
 <p>
-Plik skryptu /disc/wget-script będzie teraz zawierać listę poleceń dla
-programu wget, który uruchomi w porządku pobieranie potrzebnych archiwów.
-Skrypt ten należy uruchomić w bieżącym katalogu o punkcie montowania disc
-tak aby tu zapisywał dane na dysku.
+Plik skryptu /disc/wget-script b�dzie teraz zawiera� list� polece� dla
+programu wget, kt�ry uruchomi w porz�dku pobieranie potrzebnych archiw�w.
+Skrypt ten nale�y uruchomi� w bie��cym katalogu o punkcie montowania disc
+tak aby tu zapisywaďż˝ dane na dysku.
 
 <p>
-Na oddalonym komputerze należy wykonać coś takiego
+Na oddalonym komputerze nale�y wykona� co� takiego
 
 <example>
   # cd /disc
@@ -237,14 +237,14 @@ Na oddalonym komputerze nale
   [ czekaj.. ]
 </example>
 
-Gdy archiwa zostały pobrane i dysk wrócił do komputera z Debianem,
-instalowanie można prowadzić dalej poleceniem,
+Gdy archiwa zosta�y pobrane i dysk wr�ci� do komputera z Debianem,
+instalowanie mo�na prowadzi� dalej poleceniem,
 
 <example>
   # apt-get -o dir::cache::archives="/disc/" dist-upgrade
 </example>
 
-Które użyje pobrane uprzednio archiwa z dysku.
+Kt�re u�yje pobrane uprzednio archiwa z dysku.
 </sect>
                                                                   <!-- }}} -->
 </book>

+ 0 - 3
methods/ftp.cc

@@ -1098,9 +1098,6 @@ int main(int argc,const char *argv[])
 	 char S[300];
 	 snprintf(S,sizeof(S),"http_proxy=%s",getenv("ftp_proxy"));
 	 putenv(S);
-	 // mvo: because we switch from ftp to http we have to unset
-	 //      "no_proxy". otherwise the http method would try to 
-	 //      get a ftp url using http (see #283718)
 	 putenv("no_proxy=");
 	 
 	 // Run the http method

+ 112 - 22
po/apt-all.pot

@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2004-12-20 10:20+0100\n"
+"POT-Creation-Date: 2005-01-26 18:00+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -146,7 +146,7 @@ msgstr ""
 msgid "       %4i %s\n"
 msgstr ""
 
-#: cmdline/apt-cache.cc:1651 cmdline/apt-cdrom.cc:731 cmdline/apt-config.cc:70
+#: cmdline/apt-cache.cc:1651 cmdline/apt-cdrom.cc:353 cmdline/apt-config.cc:70
 #: cmdline/apt-extracttemplates.cc:225 ftparchive/apt-ftparchive.cc:545
 #: cmdline/apt-get.cc:2313 cmdline/apt-sortpkgs.cc:144
 #, c-format
@@ -1561,7 +1561,7 @@ msgstr ""
 msgid "Unable to accept connection"
 msgstr ""
 
-#: methods/ftp.cc:864 methods/http.cc:951 methods/rsh.cc:303
+#: methods/ftp.cc:864 methods/http.cc:916 methods/rsh.cc:303
 msgid "Problem hashing file"
 msgstr ""
 
@@ -1584,7 +1584,7 @@ msgstr ""
 msgid "Query"
 msgstr ""
 
-#: methods/ftp.cc:1107
+#: methods/ftp.cc:1106
 msgid "Unable to invoke "
 msgstr ""
 
@@ -1655,76 +1655,76 @@ msgstr ""
 msgid "Read error from %s process"
 msgstr ""
 
-#: methods/http.cc:379
+#: methods/http.cc:344
 msgid "Waiting for headers"
 msgstr ""
 
-#: methods/http.cc:525
+#: methods/http.cc:490
 #, c-format
 msgid "Got a single header line over %u chars"
 msgstr ""
 
-#: methods/http.cc:533
+#: methods/http.cc:498
 msgid "Bad header line"
 msgstr ""
 
-#: methods/http.cc:552 methods/http.cc:559
+#: methods/http.cc:517 methods/http.cc:524
 msgid "The http server sent an invalid reply header"
 msgstr ""
 
-#: methods/http.cc:588
+#: methods/http.cc:553
 msgid "The http server sent an invalid Content-Length header"
 msgstr ""
 
-#: methods/http.cc:603
+#: methods/http.cc:568
 msgid "The http server sent an invalid Content-Range header"
 msgstr ""
 
-#: methods/http.cc:605
+#: methods/http.cc:570
 msgid "This http server has broken range support"
 msgstr ""
 
-#: methods/http.cc:629
+#: methods/http.cc:594
 msgid "Unknown date format"
 msgstr ""
 
-#: methods/http.cc:772
+#: methods/http.cc:737
 msgid "Select failed"
 msgstr ""
 
-#: methods/http.cc:777
+#: methods/http.cc:742
 msgid "Connection timed out"
 msgstr ""
 
-#: methods/http.cc:800
+#: methods/http.cc:765
 msgid "Error writing to output file"
 msgstr ""
 
-#: methods/http.cc:828
+#: methods/http.cc:793
 msgid "Error writing to file"
 msgstr ""
 
-#: methods/http.cc:853
+#: methods/http.cc:818
 msgid "Error writing to the file"
 msgstr ""
 
-#: methods/http.cc:867
+#: methods/http.cc:832
 msgid "Error reading from server Remote end closed connection"
 msgstr ""
 
-#: methods/http.cc:869
+#: methods/http.cc:834
 msgid "Error reading from server"
 msgstr ""
 
-#: methods/http.cc:1100
+#: methods/http.cc:1065
 msgid "Bad header Data"
 msgstr ""
 
-#: methods/http.cc:1117
+#: methods/http.cc:1082
 msgid "Connection failed"
 msgstr ""
 
-#: methods/http.cc:1208
+#: methods/http.cc:1173
 msgid "Internal error"
 msgstr ""
 
@@ -2291,3 +2291,93 @@ msgstr ""
 #, c-format
 msgid "Vendor block %s contains no fingerprint"
 msgstr ""
+
+#: apt-pkg/cdrom.cc:487
+#, c-format
+msgid ""
+"Using CD-ROM mount point %s\n"
+"Mounting CD-ROM\n"
+msgstr ""
+
+#: apt-pkg/cdrom.cc:496 apt-pkg/cdrom.cc:578
+msgid "Identifying.. "
+msgstr ""
+
+#: apt-pkg/cdrom.cc:521
+#, c-format
+msgid "Stored Label: %s \n"
+msgstr ""
+
+#: apt-pkg/cdrom.cc:541
+#, c-format
+msgid "Using CD-ROM mount point %s\n"
+msgstr ""
+
+#: apt-pkg/cdrom.cc:559
+msgid "Unmounting CD-ROM\n"
+msgstr ""
+
+#: apt-pkg/cdrom.cc:563
+msgid "Waiting for disc...\n"
+msgstr ""
+
+#. Mount the new CDROM
+#: apt-pkg/cdrom.cc:571
+msgid "Mounting CD-ROM...\n"
+msgstr ""
+
+#: apt-pkg/cdrom.cc:589
+msgid "Scanning Disc for index files..\n"
+msgstr ""
+
+#: apt-pkg/cdrom.cc:627
+#, c-format
+msgid "Found %i package indexes, %i source indexes and %i signatures\n"
+msgstr ""
+
+#: apt-pkg/cdrom.cc:684
+msgid "That is not a valid name, try again.\n"
+msgstr ""
+
+#: apt-pkg/cdrom.cc:700
+#, c-format
+msgid ""
+"This Disc is called: \n"
+"'%s'\n"
+msgstr ""
+
+#: apt-pkg/cdrom.cc:704
+msgid "Copying package lists..."
+msgstr ""
+
+#: apt-pkg/cdrom.cc:728
+msgid "Writing new source list\n"
+msgstr ""
+
+#: apt-pkg/cdrom.cc:737
+msgid "Source List entries for this Disc are:\n"
+msgstr ""
+
+#: apt-pkg/cdrom.cc:771
+msgid "Unmounting CD-ROM..."
+msgstr ""
+
+#: apt-pkg/indexcopy.cc:261
+#, c-format
+msgid "Wrote %i records.\n"
+msgstr ""
+
+#: apt-pkg/indexcopy.cc:263
+#, c-format
+msgid "Wrote %i records with %i missing files.\n"
+msgstr ""
+
+#: apt-pkg/indexcopy.cc:266
+#, c-format
+msgid "Wrote %i records with %i mismachted files\n"
+msgstr ""
+
+#: apt-pkg/indexcopy.cc:269
+#, c-format
+msgid "Wrote %i records with %i missing files and %i mismachted files\n"
+msgstr ""