summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2019-01-23 22:50:45 +0100
committerDavid Kalnischkies <david@kalnischkies.de>2019-01-24 00:33:16 +0100
commit73e3459689c05cd62f15c29d2faddb0fc215ef5e (patch)
tree5cdddd899253499de6f9b43b171ee27a8674a0f7
parente2965b0b6bdd68ffcad0e06d11755412a7e16e50 (diff)
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.
-rw-r--r--apt-pkg/contrib/fileutl.cc6
-rw-r--r--apt-pkg/contrib/gpgv.cc78
-rw-r--r--apt-pkg/deb/debindexfile.cc11
-rw-r--r--cmdline/apt-extracttemplates.cc34
-rwxr-xr-xtest/integration/test-apt-extracttemplates7
5 files changed, 51 insertions, 85 deletions
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc
index eab05de4f..52be3a6a6 100644
--- a/apt-pkg/contrib/fileutl.cc
+++ b/apt-pkg/contrib/fileutl.cc
@@ -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;
}
/*}}}*/
diff --git a/apt-pkg/contrib/gpgv.cc b/apt-pkg/contrib/gpgv.cc
index be71b1eed..054b815fb 100644
--- a/apt-pkg/contrib/gpgv.cc
+++ b/apt-pkg/contrib/gpgv.cc
@@ -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());
diff --git a/apt-pkg/deb/debindexfile.cc b/apt-pkg/deb/debindexfile.cc
index f7e3c7a5c..25e0a3312 100644
--- a/apt-pkg/deb/debindexfile.cc
+++ b/apt-pkg/deb/debindexfile.cc
@@ -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()
{
diff --git a/cmdline/apt-extracttemplates.cc b/cmdline/apt-extracttemplates.cc
index bd23453f3..bc8a27dbe 100644
--- a/cmdline/apt-extracttemplates.cc
+++ b/cmdline/apt-extracttemplates.cc
@@ -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++)
{
diff --git a/test/integration/test-apt-extracttemplates b/test/integration/test-apt-extracttemplates
index 9b07ef79f..a47257cfd 100755
--- a/test/integration/test-apt-extracttemplates
+++ b/test/integration/test-apt-extracttemplates
@@ -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