summaryrefslogtreecommitdiff
path: root/apt-pkg
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2015-05-11 15:08:08 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2015-05-11 17:22:33 +0200
commit88593886a42025d51d76051da5929b044e42efee (patch)
tree6212ec08e3ac872573ca5faefb400a7914051bee /apt-pkg
parent8d058ea53b18348f81229049a27d14282bd8d8c1 (diff)
rewrite all TFRewrite instances to use the new pkgTagSection::Write
While it is mostly busywork to rewrite all instances it actually fixes bugs as the data storage used by the new method is std::string rather than a char*, the later mostly created by c_str() from a std::string which the caller has to ensure keeps in scope – something apt-ftparchive actually didn't ensure and relied on copy-on-write behavior instead which c++11 forbids and hence the new default gcc abi doesn't use it.
Diffstat (limited to 'apt-pkg')
-rw-r--r--apt-pkg/depcache.cc50
-rw-r--r--apt-pkg/indexcopy.cc125
-rw-r--r--apt-pkg/indexcopy.h7
3 files changed, 73 insertions, 109 deletions
diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc
index 73c5bb320..b73c336db 100644
--- a/apt-pkg/depcache.cc
+++ b/apt-pkg/depcache.cc
@@ -33,7 +33,6 @@
#include <vector>
#include <algorithm>
#include <iostream>
-#include <sstream>
#include <set>
#include <sys/stat.h>
@@ -252,17 +251,14 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly) /*{{
return _error->Error(_("Failed to open StateFile %s"),
state.c_str());
- FILE *OutFile;
- string const outfile = state + ".tmp";
- if((OutFile = fopen(outfile.c_str(),"w")) == NULL)
- return _error->Error(_("Failed to write temporary StateFile %s"),
- outfile.c_str());
+ FileFd OutFile(state, FileFd::ReadWrite | FileFd::Atomic);
+ if (OutFile.IsOpen() == false || OutFile.Failed() == true)
+ return _error->Error(_("Failed to write temporary StateFile %s"), state.c_str());
// first merge with the existing sections
pkgTagFile tagfile(&StateFile);
pkgTagSection section;
std::set<string> pkgs_seen;
- const char *nullreorderlist[] = {0};
while(tagfile.Step(section)) {
string const pkgname = section.FindS("Package");
string pkgarch = section.FindS("Architecture");
@@ -271,7 +267,7 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly) /*{{
// Silently ignore unknown packages and packages with no actual
// version.
pkgCache::PkgIterator pkg = Cache->FindPkg(pkgname, pkgarch);
- if(pkg.end() || pkg.VersionList().end())
+ if(pkg.end() || pkg.VersionList().end())
continue;
StateCache const &P = PkgState[pkg->ID];
bool newAuto = (P.Flags & Flag::Auto);
@@ -292,21 +288,17 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly) /*{{
if(_config->FindB("Debug::pkgAutoRemove",false))
std::clog << "Update existing AutoInstall info: "
<< pkg.FullName() << std::endl;
- TFRewriteData rewrite[3];
- rewrite[0].Tag = "Architecture";
- rewrite[0].Rewrite = pkg.Arch();
- rewrite[0].NewTag = 0;
- rewrite[1].Tag = "Auto-Installed";
- rewrite[1].Rewrite = newAuto ? "1" : "0";
- rewrite[1].NewTag = 0;
- rewrite[2].Tag = 0;
- TFRewrite(OutFile, section, nullreorderlist, rewrite);
- fprintf(OutFile,"\n");
+
+ std::vector<pkgTagSection::Tag> rewrite;
+ rewrite.push_back(pkgTagSection::Tag::Rewrite("Architecture", pkg.Arch()));
+ rewrite.push_back(pkgTagSection::Tag::Rewrite("Auto-Installed", newAuto ? "1" : "0"));
+ section.Write(OutFile, NULL, rewrite);
+ if (OutFile.Write("\n", 1) == false)
+ return false;
pkgs_seen.insert(pkg.FullName());
}
-
+
// then write the ones we have not seen yet
- std::ostringstream ostr;
for(pkgCache::PkgIterator pkg=Cache->PkgBegin(); !pkg.end(); ++pkg) {
StateCache const &P = PkgState[pkg->ID];
if(P.Flags & Flag::Auto) {
@@ -325,19 +317,17 @@ bool pkgDepCache::writeStateFile(OpProgress * /*prog*/, bool InstalledOnly) /*{{
continue;
if(debug_autoremove)
std::clog << "Writing new AutoInstall: " << pkg.FullName() << std::endl;
- ostr.str(string(""));
- ostr << "Package: " << pkg.Name()
- << "\nArchitecture: " << pkgarch
- << "\nAuto-Installed: 1\n\n";
- fprintf(OutFile,"%s",ostr.str().c_str());
+ std::string stanza = "Package: ";
+ stanza.append(pkg.Name())
+ .append("\nArchitecture: ").append(pkgarch)
+ .append("\nAuto-Installed: 1\n\n");
+ if (OutFile.Write(stanza.c_str(), stanza.length()) == false)
+ return false;
}
}
- fclose(OutFile);
-
- // move the outfile over the real file and set permissions
- rename(outfile.c_str(), state.c_str());
+ if (OutFile.Close() == false)
+ return false;
chmod(state.c_str(), 0644);
-
return true;
}
/*}}}*/
diff --git a/apt-pkg/indexcopy.cc b/apt-pkg/indexcopy.cc
index 144c508be..461aa4217 100644
--- a/apt-pkg/indexcopy.cc
+++ b/apt-pkg/indexcopy.cc
@@ -108,10 +108,7 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
}
if (_error->PendingError() == true)
return false;
- FILE *TargetFl = fdopen(dup(Target.Fd()),"w");
- if (TargetFl == 0)
- return _error->Errno("fdopen","Failed to reopen fd");
-
+
// Setup the progress meter
if(Progress)
Progress->OverallProgress(CurrentSize,TotalSize,FileSize,
@@ -132,14 +129,11 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
string File;
unsigned long long Size;
if (GetFile(File,Size) == false)
- {
- fclose(TargetFl);
return false;
- }
-
+
if (Chop != 0)
File = OrigPath + ChopDirs(File,Chop);
-
+
// See if the file exists
if (NoStat == false || Hits < 10)
{
@@ -157,10 +151,10 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
if (Chop != 0)
File = OrigPath + ChopDirs(File,Chop);
}
-
+
// Get the size
struct stat Buf;
- if (stat((CDROM + Prefix + File).c_str(),&Buf) != 0 ||
+ if (stat((CDROM + Prefix + File).c_str(),&Buf) != 0 ||
Buf.st_size == 0)
{
bool Mangled = false;
@@ -173,7 +167,7 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
File.replace(Start,End-Start,"binary-all");
Mangled = true;
}
-
+
if (Mangled == false ||
stat((CDROM + Prefix + File).c_str(),&Buf) != 0)
{
@@ -181,9 +175,9 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
clog << "Missed(2): " << OrigFile << endl;
NotFound++;
continue;
- }
- }
-
+ }
+ }
+
// Size match
if ((unsigned long long)Buf.st_size != Size)
{
@@ -193,21 +187,17 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
continue;
}
}
-
+
Packages++;
Hits++;
-
- if (RewriteEntry(TargetFl,File) == false)
- {
- fclose(TargetFl);
+
+ if (RewriteEntry(Target, File) == false)
return false;
- }
}
- fclose(TargetFl);
if (Debug == true)
cout << " Processed by using Prefix '" << Prefix << "' and chop " << Chop << endl;
-
+
if (_config->FindB("APT::CDROM::NoAct",false) == false)
{
// Move out of the partial directory
@@ -218,39 +208,38 @@ bool IndexCopy::CopyPackages(string CDROM,string Name,vector<string> &List,
return _error->Errno("rename","Failed to rename");
ChangeOwnerAndPermissionOfFile("CopyPackages", FinalF.c_str(), "root", "root", 0644);
}
-
+
/* Mangle the source to be in the proper notation with
- prefix dist [component] */
+ prefix dist [component] */
*I = string(*I,Prefix.length());
ConvertToSourceList(CDROM,*I);
*I = Prefix + ' ' + *I;
-
+
CurrentSize += FileSize;
- }
+ }
if(Progress)
Progress->Done();
-
+
// Some stats
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"),
+ 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 mismatched files\n"),
+ ioprintf(msg, _("Wrote %i records with %i mismatched files\n"),
Packages, WrongSize);
if (NotFound != 0 && WrongSize != 0)
ioprintf(msg, _("Wrote %i records with %i missing files and %i mismatched files\n"), Packages, NotFound, WrongSize);
}
-
+
if (Packages == 0)
_error->Warning("No valid records were found.");
if (NotFound + WrongSize > 10)
_error->Warning("A lot of entries were discarded, something may be wrong.\n");
-
return true;
}
@@ -267,10 +256,10 @@ string IndexCopy::ChopDirs(string Path,unsigned int Depth)
Depth--;
}
while (I != string::npos && Depth != 0);
-
+
if (I == string::npos)
return string();
-
+
return string(Path,I+1);
}
/*}}}*/
@@ -433,17 +422,15 @@ bool PackageCopy::GetFile(string &File,unsigned long long &Size)
}
/*}}}*/
// PackageCopy::RewriteEntry - Rewrite the entry with a new filename /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool PackageCopy::RewriteEntry(FILE *Target,string File)
+bool PackageCopy::RewriteEntry(FileFd &Target,string const &File)
{
- TFRewriteData Changes[] = {{ "Filename", File.c_str(), NULL },
- { NULL, NULL, NULL }};
-
- if (TFRewrite(Target,*Section,TFRewritePackageOrder,Changes) == false)
+ string const Dir(File,0,File.rfind('/'));
+ std::vector<pkgTagSection::Tag> Changes;
+ Changes.push_back(pkgTagSection::Tag::Rewrite("Filename", File));
+
+ if (Section->Write(Target, TFRewritePackageOrder, Changes) == false)
return false;
- fputc('\n',Target);
- return true;
+ return Target.Write("\n", 1);
}
/*}}}*/
// SourceCopy::GetFile - Get the file information from the section /*{{{*/
@@ -478,23 +465,18 @@ bool SourceCopy::GetFile(string &File,unsigned long long &Size)
}
/*}}}*/
// SourceCopy::RewriteEntry - Rewrite the entry with a new filename /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool SourceCopy::RewriteEntry(FILE *Target,string File)
+bool SourceCopy::RewriteEntry(FileFd &Target, std::string const &File)
{
- string Dir(File,0,File.rfind('/'));
- TFRewriteData Changes[] = {{ "Directory", Dir.c_str(), NULL },
- { NULL, NULL, NULL }};
-
- if (TFRewrite(Target,*Section,TFRewriteSourceOrder,Changes) == false)
+ string const Dir(File,0,File.rfind('/'));
+ std::vector<pkgTagSection::Tag> Changes;
+ Changes.push_back(pkgTagSection::Tag::Rewrite("Directory", Dir));
+
+ if (Section->Write(Target, TFRewriteSourceOrder, Changes) == false)
return false;
- fputc('\n',Target);
- return true;
+ return Target.Write("\n", 1);
}
/*}}}*/
-// SigVerify::Verify - Verify a files md5sum against its metaindex /*{{{*/
-// ---------------------------------------------------------------------
-/* */
+// SigVerify::Verify - Verify a files md5sum against its metaindex /*{{{*/
bool SigVerify::Verify(string prefix, string file, indexRecords *MetaIndex)
{
const indexRecords::checkSum *Record = MetaIndex->Lookup(file);
@@ -702,7 +684,7 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name, /*{{{*/
pkgTagFile Parser(&Pkg);
if (_error->PendingError() == true)
return false;
-
+
// Open the output file
char S[400];
snprintf(S,sizeof(S),"cdrom:[%s]/%s",Name.c_str(),
@@ -719,10 +701,7 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name, /*{{{*/
}
if (_error->PendingError() == true)
return false;
- FILE *TargetFl = fdopen(dup(Target.Fd()),"w");
- if (TargetFl == 0)
- return _error->Errno("fdopen","Failed to reopen fd");
-
+
// Setup the progress meter
if(Progress)
Progress->OverallProgress(CurrentSize,TotalSize,FileSize,
@@ -740,20 +719,16 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name, /*{{{*/
if(Progress)
Progress->Progress(Parser.Offset());
- const char *Start;
- const char *Stop;
- Section.GetSection(Start,Stop);
- fwrite(Start,Stop-Start, 1, TargetFl);
- fputc('\n',TargetFl);
+ if (Section.Write(Target) == false || Target.Write("\n", 1) == false)
+ return false;
Packages++;
Hits++;
}
- fclose(TargetFl);
if (Debug == true)
cout << " Processed by using Prefix '" << Prefix << "' and chop " << endl;
-
+
if (_config->FindB("APT::CDROM::NoAct",false) == false)
{
// Move out of the partial directory
@@ -764,34 +739,32 @@ bool TranslationsCopy::CopyTranslations(string CDROM,string Name, /*{{{*/
return _error->Errno("rename","Failed to rename");
ChangeOwnerAndPermissionOfFile("CopyTranslations", FinalF.c_str(), "root", "root", 0644);
}
-
-
+
CurrentSize += FileSize;
- }
+ }
if(Progress)
Progress->Done();
-
+
// Some stats
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"),
+ 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 mismatched files\n"),
+ ioprintf(msg, _("Wrote %i records with %i mismatched files\n"),
Packages, WrongSize);
if (NotFound != 0 && WrongSize != 0)
ioprintf(msg, _("Wrote %i records with %i missing files and %i mismatched files\n"), Packages, NotFound, WrongSize);
}
-
+
if (Packages == 0)
_error->Warning("No valid records were found.");
if (NotFound + WrongSize > 10)
_error->Warning("A lot of entries were discarded, something may be wrong.\n");
-
return true;
}
diff --git a/apt-pkg/indexcopy.h b/apt-pkg/indexcopy.h
index 701beb075..729b0c8cb 100644
--- a/apt-pkg/indexcopy.h
+++ b/apt-pkg/indexcopy.h
@@ -28,6 +28,7 @@ using std::vector;
class pkgTagSection;
class indexRecords;
class pkgCdromStatus;
+class FileFd;
class IndexCopy /*{{{*/
{
@@ -45,7 +46,7 @@ class IndexCopy /*{{{*/
void ConvertToSourceList(std::string CD,std::string &Path);
bool GrabFirst(std::string Path,std::string &To,unsigned int Depth);
virtual bool GetFile(std::string &Filename,unsigned long long &Size) = 0;
- virtual bool RewriteEntry(FILE *Target,std::string File) = 0;
+ virtual bool RewriteEntry(FileFd &Target, std::string const &File) = 0;
virtual const char *GetFileName() = 0;
virtual const char *Type() = 0;
@@ -61,7 +62,7 @@ class PackageCopy : public IndexCopy /*{{{*/
protected:
virtual bool GetFile(std::string &Filename,unsigned long long &Size);
- virtual bool RewriteEntry(FILE *Target,std::string File);
+ virtual bool RewriteEntry(FileFd &Target, std::string const &File);
virtual const char *GetFileName() {return "Packages";};
virtual const char *Type() {return "Package";};
@@ -72,7 +73,7 @@ class SourceCopy : public IndexCopy /*{{{*/
protected:
virtual bool GetFile(std::string &Filename,unsigned long long &Size);
- virtual bool RewriteEntry(FILE *Target,std::string File);
+ virtual bool RewriteEntry(FileFd &Target, std::string const &File);
virtual const char *GetFileName() {return "Sources";};
virtual const char *Type() {return "Source";};