Browse Source

Merge and reuse tmp file handling across the board

Having many rather similar implementations especially if one is exported
while others aren't (and the rest of it not factored out at all) seems
suboptimal.
tags/debian/1.8.0_rc1
David Kalnischkies 2 years ago
parent
commit
73e3459689
5 changed files with 51 additions and 85 deletions
  1. +4
    -2
      apt-pkg/contrib/fileutl.cc
  2. +25
    -53
      apt-pkg/contrib/gpgv.cc
  3. +4
    -7
      apt-pkg/deb/debindexfile.cc
  4. +11
    -23
      cmdline/apt-extracttemplates.cc
  5. +7
    -0
      test/integration/test-apt-extracttemplates

+ 4
- 2
apt-pkg/contrib/fileutl.cc View File

@@ -3114,7 +3114,7 @@ FileFd* GetTempFile(std::string const &Prefix, bool ImmediateUnlink, FileFd * co
snprintf(fn, sizeof(fn), "%s/%s.XXXXXX",
tempdir.c_str(), Prefix.c_str());
int const fd = mkstemp(fn);
if(ImmediateUnlink)
if (ImmediateUnlink)
unlink(fn);
if (fd < 0)
{
@@ -3123,13 +3123,15 @@ FileFd* GetTempFile(std::string const &Prefix, bool ImmediateUnlink, FileFd * co
delete Fd;
return nullptr;
}
if (!Fd->OpenDescriptor(fd, FileFd::ReadWrite, FileFd::None, true))
if (!Fd->OpenDescriptor(fd, FileFd::ReadWrite | FileFd::BufferedWrite, FileFd::None, true))
{
_error->Errno("GetTempFile",_("Unable to write to %s"),fn);
if (TmpFd == nullptr)
delete Fd;
return nullptr;
}
if (ImmediateUnlink == false)
Fd->SetFileName(fn);
return Fd;
}
/*}}}*/


+ 25
- 53
apt-pkg/contrib/gpgv.cc View File

@@ -49,14 +49,6 @@ static bool GetLineErrno(std::unique_ptr<char, decltype(&free)> &buffer, size_t
return true;
}
/*}}}*/
static char * GenerateTemporaryFileTemplate(const char *basename) /*{{{*/
{
std::string out;
std::string tmpdir = GetTempDir();
strprintf(out, "%s/%s.XXXXXX", tmpdir.c_str(), basename);
return strdup(out.c_str());
}
/*}}}*/
// ExecGPGV - returns the command needed for verify /*{{{*/
// ---------------------------------------------------------------------
/* Generating the commandline for calling gpg is somehow complicated as
@@ -171,29 +163,33 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG,
}

enum { DETACHED, CLEARSIGNED } releaseSignature = (FileGPG != File) ? DETACHED : CLEARSIGNED;
char * sig = NULL;
char * data = NULL;
char * conf = nullptr;
std::unique_ptr<char, decltype(&free)> sig{nullptr, &free};
std::unique_ptr<char, decltype(&free)> data{nullptr, &free};
std::unique_ptr<char, decltype(&free)> conf{nullptr, &free};

// Dump the configuration so apt-key picks up the correct Dir values
{
conf = GenerateTemporaryFileTemplate("apt.conf");
{
std::string tmpfile;
strprintf(tmpfile, "%s/apt.conf.XXXXXX", GetTempDir().c_str());
conf.reset(strdup(tmpfile.c_str()));
}
if (conf == nullptr) {
apt_error(std::cerr, statusfd, fd, "Couldn't create tempfile names for passing config to apt-key");
local_exit(EINTERNAL);
}
int confFd = mkstemp(conf);
int confFd = mkstemp(conf.get());
if (confFd == -1) {
apt_error(std::cerr, statusfd, fd, "Couldn't create temporary file %s for passing config to apt-key", conf);
apt_error(std::cerr, statusfd, fd, "Couldn't create temporary file %s for passing config to apt-key", conf.get());
local_exit(EINTERNAL);
}
local_exit.files.push_back(conf);
local_exit.files.push_back(conf.get());

std::ofstream confStream(conf);
std::ofstream confStream(conf.get());
close(confFd);
_config->Dump(confStream);
confStream.close();
setenv("APT_CONFIG", conf, 1);
setenv("APT_CONFIG", conf.get(), 1);
}

if (releaseSignature == DETACHED)
@@ -245,30 +241,16 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG,
}
else // clear-signed file
{
sig = GenerateTemporaryFileTemplate("apt.sig");
data = GenerateTemporaryFileTemplate("apt.data");
if (sig == NULL || data == NULL)
{
apt_error(std::cerr, statusfd, fd, "Couldn't create tempfile names for splitting up %s", File.c_str());
local_exit(EINTERNAL);
}

int const sigFd = mkstemp(sig);
int const dataFd = mkstemp(data);
if (dataFd != -1)
local_exit.files.push_back(data);
if (sigFd != -1)
local_exit.files.push_back(sig);
if (sigFd == -1 || dataFd == -1)
{
apt_error(std::cerr, statusfd, fd, "Couldn't create tempfiles for splitting up %s", File.c_str());
local_exit(EINTERNAL);
}

FileFd signature;
signature.OpenDescriptor(sigFd, FileFd::WriteOnly, true);
if (GetTempFile("apt.sig", false, &signature) == nullptr)
local_exit(EINTERNAL);
sig.reset(strdup(signature.Name().c_str()));
local_exit.files.push_back(sig.get());
FileFd message;
message.OpenDescriptor(dataFd, FileFd::WriteOnly, true);
if (GetTempFile("apt.data", false, &message) == nullptr)
local_exit(EINTERNAL);
data.reset(strdup(message.Name().c_str()));
local_exit.files.push_back(data.get());

if (signature.Failed() == true || message.Failed() == true ||
SplitClearSignedFile(File, &message, nullptr, &signature) == false)
@@ -276,8 +258,8 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG,
apt_error(std::cerr, statusfd, fd, "Splitting up %s into data and signature failed", File.c_str());
local_exit(112);
}
Args.push_back(sig);
Args.push_back(data);
Args.push_back(sig.get());
Args.push_back(data.get());
}

Args.push_back(NULL);
@@ -464,18 +446,8 @@ bool SplitClearSignedFile(std::string const &InFile, FileFd * const ContentFile,
/*}}}*/
bool OpenMaybeClearSignedFile(std::string const &ClearSignedFileName, FileFd &MessageFile) /*{{{*/
{
char * const message = GenerateTemporaryFileTemplate("fileutl.message");
int const messageFd = mkstemp(message);
if (messageFd == -1)
{
free(message);
return _error->Errno("mkstemp", "Couldn't create temporary file to work with %s", ClearSignedFileName.c_str());
}
// we have the fd, that's enough for us
unlink(message);
free(message);

MessageFile.OpenDescriptor(messageFd, FileFd::ReadWrite | FileFd::BufferedWrite, true);
if (GetTempFile("clearsigned.message", true, &MessageFile) == nullptr)
return false;
if (MessageFile.Failed() == true)
return _error->Error("Couldn't open temporary file to work with %s", ClearSignedFileName.c_str());



+ 4
- 7
apt-pkg/deb/debindexfile.cc View File

@@ -315,13 +315,10 @@ const pkgIndexFile::Type *debStringPackageIndex::GetType() const
debStringPackageIndex::debStringPackageIndex(std::string const &content) :
pkgDebianIndexRealFile("", false), d(NULL)
{
char fn[1024];
std::string const tempdir = GetTempDir();
snprintf(fn, sizeof(fn), "%s/%s.XXXXXX", tempdir.c_str(), "apt-tmp-index");
int const fd = mkstemp(fn);
File = fn;
FileFd::Write(fd, content.data(), content.length());
close(fd);
FileFd fd;
GetTempFile("apt-tmp-index", false, &fd);
fd.Write(content.data(), content.length());
File = fd.Name();
}
debStringPackageIndex::~debStringPackageIndex()
{


+ 11
- 23
cmdline/apt-extracttemplates.cc View File

@@ -229,29 +229,13 @@ static bool ShowHelp(CommandLine &) /*{{{*/
/* */
static string WriteFile(const char *package, const char *prefix, const char *data)
{
char fn[512];

std::string tempdir = GetTempDir();
snprintf(fn, sizeof(fn), "%s/%s.%s.XXXXXX",
_config->Find("APT::ExtractTemplates::TempDir",
tempdir.c_str()).c_str(),
package, prefix);
FileFd f;
if (data == NULL)
data = "";
int fd = mkstemp(fn);
if (fd < 0) {
_error->Errno("ofstream::ofstream",_("Unable to mkstemp %s"),fn);
return string();
}
if (!f.OpenDescriptor(fd, FileFd::WriteOnly, FileFd::None, true))
{
_error->Errno("ofstream::ofstream",_("Unable to write to %s"),fn);
return string();
}
f.Write(data, strlen(data));
f.Close();
return fn;
FileFd f;
std::string tplname;
strprintf(tplname, "%s.%s", package, prefix);
GetTempFile(tplname, false, &f);
if (data != nullptr)
f.Write(data, strlen(data));
return f.Name();
}
/*}}}*/
// WriteConfig - write out the config data from a debian package file /*{{{*/
@@ -289,6 +273,10 @@ static bool Go(CommandLine &CmdL)
if (debconfver.empty() == true)
return _error->Error( _("Cannot get debconf version. Is debconf installed?"));

auto const tmpdir = _config->Find("APT::ExtractTemplates::TempDir");
if (tmpdir.empty() == false)
setenv("TMPDIR", tmpdir.c_str(), 1);

// Process each package passsed in
for (unsigned int I = 0; I != CmdL.FileSize(); I++)
{


+ 7
- 0
test/integration/test-apt-extracttemplates View File

@@ -44,6 +44,13 @@ Description: Some bar var
testfileequal "$TEMPLATE" "$TEMPLATE_STR"
CONFIG=$(cut -f4 -d' ' $OUT)
testfileequal "$CONFIG" "$CONFIG_STR"
msgtest 'No extra files or directories in extraction directory'
if [ "$(find ./extracttemplates-out | wc -l)" = '3' ]; then
msgpass
else
msgfail
ls -l ./extracttemplates-out
fi

# ensure that the format of the output string has the right number of dots
for s in "$CONFIG" "$TEMPLATE"; do


Loading…
Cancel
Save