diff options
-rw-r--r-- | apt-pkg/cdrom.cc | 776 | ||||
-rw-r--r-- | apt-pkg/cdrom.h | 71 | ||||
-rw-r--r-- | apt-pkg/contrib/sha1.cc | 11 | ||||
-rw-r--r-- | apt-pkg/indexcopy.cc (renamed from cmdline/indexcopy.cc) | 208 | ||||
-rw-r--r-- | apt-pkg/indexcopy.h (renamed from cmdline/indexcopy.h) | 16 | ||||
-rw-r--r-- | apt-pkg/indexrecords.cc | 11 | ||||
-rw-r--r-- | apt-pkg/indexrecords.h | 4 | ||||
-rw-r--r-- | apt-pkg/makefile | 6 | ||||
-rw-r--r-- | cmdline/apt-cdrom.cc | 705 | ||||
-rw-r--r-- | cmdline/makefile | 2 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | debian/apt.cron.daily | 1 | ||||
-rw-r--r-- | debian/changelog | 15 | ||||
-rwxr-xr-x | debian/rules | 4 | ||||
-rw-r--r-- | doc/pl/offline.pl.sgml | 180 | ||||
-rw-r--r-- | methods/ftp.cc | 3 | ||||
-rw-r--r-- | po/apt-all.pot | 134 |
17 files changed, 1328 insertions, 821 deletions
diff --git a/apt-pkg/cdrom.cc b/apt-pkg/cdrom.cc new file mode 100644 index 000000000..a91fc7181 --- /dev/null +++ b/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; +} diff --git a/apt-pkg/cdrom.h b/apt-pkg/cdrom.h new file mode 100644 index 000000000..085eb64e2 --- /dev/null +++ b/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 diff --git a/apt-pkg/contrib/sha1.cc b/apt-pkg/contrib/sha1.cc index a22b4d2b2..9b402c523 100644 --- a/apt-pkg/contrib/sha1.cc +++ b/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); } diff --git a/cmdline/indexcopy.cc b/apt-pkg/indexcopy.cc index 0a3cd1575..901001891 100644 --- a/cmdline/indexcopy.cc +++ b/apt-pkg/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; +} diff --git a/cmdline/indexcopy.h b/apt-pkg/indexcopy.h index e44a91727..fa8e9c156 100644 --- a/cmdline/indexcopy.h +++ b/apt-pkg/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 diff --git a/apt-pkg/indexrecords.cc b/apt-pkg/indexrecords.cc index c4b8a8235..06ed7921c 100644 --- a/apt-pkg/indexrecords.cc +++ b/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) { diff --git a/apt-pkg/indexrecords.h b/apt-pkg/indexrecords.h index 277280620..414faceaa 100644 --- a/apt-pkg/indexrecords.h +++ b/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; diff --git a/apt-pkg/makefile b/apt-pkg/makefile index 41045f91a..5f48f0f52 100644 --- a/apt-pkg/makefile +++ b/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.. diff --git a/cmdline/apt-cdrom.cc b/cmdline/apt-cdrom.cc index 7367a55a3..8010e7b53 100644 --- a/cmdline/apt-cdrom.cc +++ b/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); } /*}}}*/ diff --git a/cmdline/makefile b/cmdline/makefile index 21a6d47d4..882a0e1b5 100644 --- a/cmdline/makefile +++ b/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 diff --git a/configure.in b/configure.in index da10634a3..6b57dec27 100644 --- a/configure.in +++ b/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) diff --git a/debian/apt.cron.daily b/debian/apt.cron.daily index 17fe8fb78..3e6b384d2 100644 --- a/debian/apt.cron.daily +++ b/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 diff --git a/debian/changelog b/debian/changelog index b98ecbf81..c384c399d 100644 --- a/debian/changelog +++ b/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 diff --git a/debian/rules b/debian/rules index 71d6d549e..e3254c2d2 100755 --- a/debian/rules +++ b/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$@ diff --git a/doc/pl/offline.pl.sgml b/doc/pl/offline.pl.sgml index 48f84e3b1..2adb2554d 100644 --- a/doc/pl/offline.pl.sgml +++ b/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 © Jason Gunthorpe, 1999. <p> -Copyright © polskiego tłumaczenia Krzysztof Fiertek, 2004. +Copyright © 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ądać następująco: <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żyć tych samych odnośników o identycznej składni. 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żyć tych samych odnośników o identycznej składni. }; </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ży wykonać coś takiego [ 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> diff --git a/methods/ftp.cc b/methods/ftp.cc index c115e165d..fafa10534 100644 --- a/methods/ftp.cc +++ b/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 diff --git a/po/apt-all.pot b/po/apt-all.pot index b7062c588..c91fca021 100644 --- a/po/apt-all.pot +++ b/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 "" |