##################################################################### */
/*}}}*/
// Include Files /*{{{*/
-#include "indexcopy.h"
+#include<config.h>
#include <apt-pkg/error.h>
#include <apt-pkg/progress.h>
#include <apt-pkg/indexrecords.h>
#include <apt-pkg/md5.h>
#include <apt-pkg/cdrom.h>
-#include <apti18n.h>
#include <iostream>
#include <sstream>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
+#include <stdlib.h>
+
+#include "indexcopy.h"
+#include <apti18n.h>
/*}}}*/
using namespace std;
-
-
+// DecompressFile - wrapper for decompressing gzip/bzip2/xz compressed files /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+bool DecompressFile(string Filename, int *fd, off_t *FileSize)
+{
+ string CompressProg;
+ string CompressProgFind;
+ FileFd From;
+ struct stat Buf;
+ *fd = -1;
+
+ if (stat((Filename + ".gz").c_str(), &Buf) == 0)
+ {
+ CompressProg = "gzip";
+ CompressProgFind = "Dir::bin::gzip";
+ From.Open(Filename + ".gz",FileFd::ReadOnly);
+ }
+ else if (stat((Filename + ".bz2").c_str(), &Buf) == 0)
+ {
+ CompressProg = "bzip2";
+ CompressProgFind = "Dir::bin::bzip2";
+ From.Open(Filename + ".bz2",FileFd::ReadOnly);
+ }
+ else if (stat((Filename + ".xz").c_str(), &Buf) == 0)
+ {
+ CompressProg = "xz";
+ CompressProgFind = "Dir::bin::xz";
+ From.Open(Filename + ".xz",FileFd::ReadOnly);
+ }
+ else
+ {
+ return _error->Errno("decompressor", "Unable to parse file");
+ }
+
+ if (_error->PendingError() == true)
+ return -1;
+
+ *FileSize = Buf.st_size;
+
+ // Get a temp file
+ FILE *tmp = tmpfile();
+ if (tmp == 0)
+ return _error->Errno("tmpfile","Unable to create a tmp file");
+ *fd = dup(fileno(tmp));
+ fclose(tmp);
+
+ // Fork decompressor
+ pid_t Process = fork();
+ if (Process < 0)
+ return _error->Errno("fork","Couldn't fork to run decompressor");
+
+ // The child
+ if (Process == 0)
+ {
+ dup2(From.Fd(),STDIN_FILENO);
+ dup2(*fd,STDOUT_FILENO);
+ SetCloseExec(STDIN_FILENO,false);
+ SetCloseExec(STDOUT_FILENO,false);
+
+ const char *Args[3];
+ string Tmp = _config->Find(CompressProgFind, CompressProg);
+ Args[0] = Tmp.c_str();
+ Args[1] = "-d";
+ Args[2] = 0;
+ if(execvp(Args[0],(char **)Args))
+ return(_error->Errno("decompressor","decompress failed"));
+ /* Should never get here */
+ exit(100);
+ }
+
+ // Wait for decompress to finish
+ if (ExecWait(Process,CompressProg.c_str(),false) == false)
+ return false;
+
+ return true;
+}
+ /*}}}*/
// IndexCopy::CopyPackages - Copy the package files from the CD /*{{{*/
// ---------------------------------------------------------------------
/* */
pkgCdromStatus *log)
{
OpProgress *Progress = NULL;
- if (List.size() == 0)
+ if (List.empty() == true)
return true;
if(log)
bool Debug = _config->FindB("Debug::aptcdrom",false);
// Prepare the progress indicator
- unsigned long TotalSize = 0;
- for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
+ off_t TotalSize = 0;
+ for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
{
struct stat Buf;
if (stat(string(*I + GetFileName()).c_str(),&Buf) != 0 &&
- stat(string(*I + GetFileName() + ".gz").c_str(),&Buf) != 0)
+ stat(string(*I + GetFileName() + ".gz").c_str(),&Buf) != 0 &&
+ stat(string(*I + GetFileName() + ".xz").c_str(),&Buf) != 0 &&
+ stat(string(*I + GetFileName() + ".bz2").c_str(),&Buf) != 0)
return _error->Errno("stat","Stat failed for %s",
string(*I + GetFileName()).c_str());
TotalSize += Buf.st_size;
}
- unsigned long CurrentSize = 0;
+ off_t CurrentSize = 0;
unsigned int NotFound = 0;
unsigned int WrongSize = 0;
unsigned int Packages = 0;
- for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
+ for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
{
string OrigPath = string(*I,CDROM.length());
- unsigned long FileSize = 0;
+ off_t FileSize = 0;
// Open the package file
FileFd Pkg;
- if (FileExists(*I + GetFileName()) == true)
+ if (RealFileExists(*I + GetFileName()) == true)
{
Pkg.Open(*I + GetFileName(),FileFd::ReadOnly);
FileSize = Pkg.Size();
}
else
{
- FileFd From(*I + GetFileName() + ".gz",FileFd::ReadOnly);
- if (_error->PendingError() == true)
- return false;
- FileSize = From.Size();
-
- // Get a temp file
- FILE *tmp = tmpfile();
- if (tmp == 0)
- return _error->Errno("tmpfile","Unable to create a tmp file");
- Pkg.Fd(dup(fileno(tmp)));
- fclose(tmp);
-
- // Fork gzip
- pid_t Process = fork();
- if (Process < 0)
- return _error->Errno("fork","Couldn't fork gzip");
-
- // The child
- if (Process == 0)
- {
- dup2(From.Fd(),STDIN_FILENO);
- dup2(Pkg.Fd(),STDOUT_FILENO);
- SetCloseExec(STDIN_FILENO,false);
- SetCloseExec(STDOUT_FILENO,false);
-
- const char *Args[3];
- string Tmp = _config->Find("Dir::bin::gzip","gzip");
- Args[0] = Tmp.c_str();
- Args[1] = "-d";
- Args[2] = 0;
- execvp(Args[0],(char **)Args);
- exit(100);
- }
-
- // Wait for gzip to finish
- if (ExecWait(Process,_config->Find("Dir::bin::gzip","gzip").c_str(),false) == false)
- return _error->Error("gzip failed, perhaps the disk is full.");
-
+ int fd;
+ if (!DecompressFile(string(*I + GetFileName()), &fd, &FileSize))
+ return _error->Errno("decompress","Decompress failed for %s",
+ string(*I + GetFileName()).c_str());
+ Pkg.Fd(dup(fd));
Pkg.Seek(0);
}
+
pkgTagFile Parser(&Pkg);
if (_error->PendingError() == true)
return false;
(*I).c_str() + CDROM.length(),GetFileName());
string TargetF = _config->FindDir("Dir::State::lists") + "partial/";
TargetF += URItoFileName(S);
+ FileFd Target;
if (_config->FindB("APT::CDROM::NoAct",false) == true)
+ {
TargetF = "/dev/null";
- FileFd Target(TargetF,FileFd::WriteAtomic);
+ Target.Open(TargetF,FileFd::WriteExists);
+ } else {
+ Target.Open(TargetF,FileFd::WriteAtomic);
+ }
FILE *TargetFl = fdopen(dup(Target.Fd()),"w");
if (_error->PendingError() == true)
return false;
if(Progress)
Progress->Progress(Parser.Offset());
string File;
- unsigned long Size;
+ unsigned long long Size;
if (GetFile(File,Size) == false)
{
fclose(TargetFl);
}
// Size match
- if ((unsigned)Buf.st_size != Size)
+ if ((unsigned long long)Buf.st_size != Size)
{
if (Debug == true)
clog << "Wrong Size: " << File << endl;
// PackageCopy::GetFile - Get the file information from the section /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool PackageCopy::GetFile(string &File,unsigned long &Size)
+bool PackageCopy::GetFile(string &File,unsigned long long &Size)
{
File = Section->FindS("Filename");
Size = Section->FindI("Size");
// SourceCopy::GetFile - Get the file information from the section /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool SourceCopy::GetFile(string &File,unsigned long &Size)
+bool SourceCopy::GetFile(string &File,unsigned long long &Size)
{
string Files = Section->FindS("Files");
if (Files.empty() == true)
return _error->Error("Error parsing file record");
// Parse the size and append the directory
- Size = atoi(sSize.c_str());
+ Size = strtoull(sSize.c_str(), NULL, 10);
File = Base + File;
return true;
}
// we skip non-existing files in the verifcation to support a cdrom
// with no Packages file (just a Package.gz), see LP: #255545
// (non-existing files are not considered a error)
- if(!FileExists(prefix+file))
+ if(!RealFileExists(prefix+file))
{
_error->Warning(_("Skipping nonexistent file %s"), string(prefix+file).c_str());
return true;
bool SigVerify::CopyAndVerify(string CDROM,string Name,vector<string> &SigList, /*{{{*/
vector<string> PkgList,vector<string> SrcList)
{
- if (SigList.size() == 0)
+ if (SigList.empty() == true)
return true;
bool Debug = _config->FindB("Debug::aptcdrom",false);
// Read all Release files
- for (vector<string>::iterator I = SigList.begin(); I != SigList.end(); I++)
+ for (vector<string>::iterator I = SigList.begin(); I != SigList.end(); ++I)
{
if(Debug)
cout << "Signature verify for: " << *I << endl;
string const release = *I+"Release";
// a Release.gpg without a Release should never happen
- if(FileExists(release) == false)
+ if(RealFileExists(release) == false)
{
delete MetaIndex;
continue;
// 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++)
+ 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
bool SigVerify::RunGPGV(std::string const &File, std::string const &FileGPG,
int const &statusfd, int fd[2])
{
+ if (File == FileGPG)
+ {
+ #define SIGMSG "-----BEGIN PGP SIGNED MESSAGE-----\n"
+ char buffer[sizeof(SIGMSG)];
+ FILE* gpg = fopen(File.c_str(), "r");
+ if (gpg == NULL)
+ return _error->Errno("RunGPGV", _("Could not open file %s"), File.c_str());
+ char const * const test = fgets(buffer, sizeof(buffer), gpg);
+ fclose(gpg);
+ if (test == NULL || strcmp(buffer, SIGMSG) != 0)
+ return _error->Error(_("File %s doesn't start with a clearsigned message"), File.c_str());
+ #undef SIGMSG
+ }
+
+
string const gpgvpath = _config->Find("Dir::Bin::gpg", "/usr/bin/gpgv");
// FIXME: remove support for deprecated APT::GPGV setting
- string const trustedFile = _config->FindFile("Dir::Etc::Trusted");
+ string const trustedFile = _config->Find("APT::GPGV::TrustedKeyring", _config->FindFile("Dir::Etc::Trusted"));
string const trustedPath = _config->FindDir("Dir::Etc::TrustedParts");
bool const Debug = _config->FindB("Debug::Acquire::gpgv", false);
std::clog << "Keyring path: " << trustedPath << std::endl;
}
- std::vector<string> keyrings = GetListOfFilesInDir(trustedPath, "gpg", false);
- if (FileExists(trustedFile) == true)
- keyrings.push_back(trustedFile);
+ std::vector<string> keyrings;
+ if (DirectoryExists(trustedPath))
+ keyrings = GetListOfFilesInDir(trustedPath, "gpg", false, true);
+ if (RealFileExists(trustedFile) == true)
+ keyrings.push_back(trustedFile);
std::vector<const char *> Args;
Args.reserve(30);
if (keyrings.empty() == true)
- return false;
+ {
+ // TRANSLATOR: %s is the trusted keyring parts directory
+ return _error->Error(_("No keyring installed in %s."),
+ _config->FindDir("Dir::Etc::TrustedParts").c_str());
+ }
Args.push_back(gpgvpath.c_str());
Args.push_back("--ignore-time-conflict");
}
Args.push_back(FileGPG.c_str());
- Args.push_back(File.c_str());
+ if (FileGPG != File)
+ Args.push_back(File.c_str());
Args.push_back(NULL);
if (Debug == true)
vector<string> &List, pkgCdromStatus *log)
{
OpProgress *Progress = NULL;
- if (List.size() == 0)
+ if (List.empty() == true)
return true;
if(log)
bool Debug = _config->FindB("Debug::aptcdrom",false);
// Prepare the progress indicator
- unsigned long TotalSize = 0;
- for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
+ off_t TotalSize = 0;
+ for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
{
struct stat Buf;
+
if (stat(string(*I).c_str(),&Buf) != 0 &&
- stat(string(*I + ".gz").c_str(),&Buf) != 0)
+ stat(string(*I + ".gz").c_str(),&Buf) != 0 &&
+ stat(string(*I + ".bz2").c_str(),&Buf) != 0 &&
+ stat(string(*I + ".xz").c_str(),&Buf) != 0)
return _error->Errno("stat","Stat failed for %s",
string(*I).c_str());
TotalSize += Buf.st_size;
}
- unsigned long CurrentSize = 0;
+ off_t CurrentSize = 0;
unsigned int NotFound = 0;
unsigned int WrongSize = 0;
unsigned int Packages = 0;
- for (vector<string>::iterator I = List.begin(); I != List.end(); I++)
+ for (vector<string>::iterator I = List.begin(); I != List.end(); ++I)
{
string OrigPath = string(*I,CDROM.length());
- unsigned long FileSize = 0;
+ off_t FileSize = 0;
// Open the package file
FileFd Pkg;
- if (FileExists(*I) == true)
+ if (RealFileExists(*I) == true)
{
Pkg.Open(*I,FileFd::ReadOnly);
FileSize = Pkg.Size();
}
else
{
- FileFd From(*I + ".gz",FileFd::ReadOnly);
- if (_error->PendingError() == true)
- return false;
- FileSize = From.Size();
-
- // Get a temp file
- FILE *tmp = tmpfile();
- if (tmp == 0)
- return _error->Errno("tmpfile","Unable to create a tmp file");
- Pkg.Fd(dup(fileno(tmp)));
- fclose(tmp);
-
- // Fork gzip
- pid_t Process = fork();
- if (Process < 0)
- return _error->Errno("fork","Couldn't fork gzip");
-
- // The child
- if (Process == 0)
- {
- dup2(From.Fd(),STDIN_FILENO);
- dup2(Pkg.Fd(),STDOUT_FILENO);
- SetCloseExec(STDIN_FILENO,false);
- SetCloseExec(STDOUT_FILENO,false);
-
- const char *Args[3];
- string Tmp = _config->Find("Dir::bin::gzip","gzip");
- Args[0] = Tmp.c_str();
- Args[1] = "-d";
- Args[2] = 0;
- execvp(Args[0],(char **)Args);
- exit(100);
- }
-
- // Wait for gzip to finish
- if (ExecWait(Process,_config->Find("Dir::bin::gzip","gzip").c_str(),false) == false)
- return _error->Error("gzip failed, perhaps the disk is full.");
-
+ int fd;
+ if (!DecompressFile(*I, &fd, &FileSize))
+ return _error->Errno("decompress","Decompress failed for %s", (*I).c_str());
+ Pkg.Fd(dup(fd));
Pkg.Seek(0);
}
pkgTagFile Parser(&Pkg);
this->Section = &Section;
string Prefix;
unsigned long Hits = 0;
- unsigned long Chop = 0;
while (Parser.Step(Section) == true)
{
if(Progress)
fclose(TargetFl);
if (Debug == true)
- cout << " Processed by using Prefix '" << Prefix << "' and chop " << Chop << endl;
+ cout << " Processed by using Prefix '" << Prefix << "' and chop " << endl;
if (_config->FindB("APT::CDROM::NoAct",false) == false)
{