#include <vector>
#include <algorithm>
#include <iostream>
-#include <sstream>
#include <set>
#include <sys/stat.h>
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");
// 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);
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) {
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;
}
/*}}}*/
}
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,
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)
{
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;
File.replace(Start,End-Start,"binary-all");
Mangled = true;
}
-
+
if (Mangled == false ||
stat((CDROM + Prefix + File).c_str(),&Buf) != 0)
{
clog << "Missed(2): " << OrigFile << endl;
NotFound++;
continue;
- }
- }
-
+ }
+ }
+
// Size match
if ((unsigned long long)Buf.st_size != Size)
{
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
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;
}
Depth--;
}
while (I != string::npos && Depth != 0);
-
+
if (I == string::npos)
return string();
-
+
return string(Path,I+1);
}
/*}}}*/
}
/*}}}*/
// 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 /*{{{*/
}
/*}}}*/
// 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);
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(),
}
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,
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
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;
}
class pkgTagSection;
class indexRecords;
class pkgCdromStatus;
+class FileFd;
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;
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";};
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";};
manual_installed = 0;
// FIXME: add verbose that does not do the removal of the tags?
- TFRewriteData RW[] = {
- // delete, apt-cache show has this info and most users do not care
- {"MD5sum", NULL, NULL},
- {"SHA1", NULL, NULL},
- {"SHA256", NULL, NULL},
- {"Filename", NULL, NULL},
- {"Multi-Arch", NULL, NULL},
- {"Architecture", NULL, NULL},
- {"Conffiles", NULL, NULL},
- // we use the translated description
- {"Description", NULL, NULL},
- {"Description-md5", NULL, NULL},
- // improve
- {"Installed-Size", installed_size.c_str(), NULL},
- {"Size", package_size.c_str(), "Download-Size"},
- // add
- {"APT-Manual-Installed", manual_installed, NULL},
- {"APT-Sources", source_index_file.c_str(), NULL},
- {NULL, NULL, NULL}
- };
-
- if(TFRewrite(stdout, Tags, NULL, RW) == false)
+ std::vector<pkgTagSection::Tag> RW;
+ // delete, apt-cache show has this info and most users do not care
+ RW.push_back(pkgTagSection::Tag::Remove("MD5sum"));
+ RW.push_back(pkgTagSection::Tag::Remove("SHA1"));
+ RW.push_back(pkgTagSection::Tag::Remove("SHA256"));
+ RW.push_back(pkgTagSection::Tag::Remove("SHA512"));
+ RW.push_back(pkgTagSection::Tag::Remove("Filename"));
+ RW.push_back(pkgTagSection::Tag::Remove("Multi-Arch"));
+ RW.push_back(pkgTagSection::Tag::Remove("Architecture"));
+ RW.push_back(pkgTagSection::Tag::Remove("Conffiles"));
+ // we use the translated description
+ RW.push_back(pkgTagSection::Tag::Remove("Description"));
+ RW.push_back(pkgTagSection::Tag::Remove("Description-md5"));
+ // improve
+ RW.push_back(pkgTagSection::Tag::Rewrite("Installed-Size", installed_size));
+ RW.push_back(pkgTagSection::Tag::Remove("Size"));
+ RW.push_back(pkgTagSection::Tag::Rewrite("Download-Size", package_size));
+ // add
+ RW.push_back(pkgTagSection::Tag::Rewrite("APT-Manual-Installed", manual_installed));
+ RW.push_back(pkgTagSection::Tag::Rewrite("APT-Sources", source_index_file));
+
+ FileFd stdoutfd;
+ if (stdoutfd.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly, false) == false ||
+ Tags.Write(stdoutfd, TFRewritePackageOrder, RW) == false || stdoutfd.Close() == false)
return _error->Error("Internal Error, Unable to parse a package record");
// write the description
LocalitySort(VFList,Count,sizeof(*VFList));
+ std::vector<pkgTagSection::Tag> RW;
+ RW.push_back(pkgTagSection::Tag::Remove("Status"));
+ RW.push_back(pkgTagSection::Tag::Remove("Config-Version"));
+ FileFd stdoutfd;
+ stdoutfd.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly, false);
+
// Iterate over all the package files and write them out.
char *Buffer = new char[Cache->HeaderP->MaxVerFileSize+10];
for (pkgCache::VerFile **J = VFList; *J != 0;)
if (PkgF.Read(Buffer,VF.Size + Jitter) == false)
break;
Buffer[VF.Size + Jitter] = '\n';
-
+
// See above..
if ((File->Flags & pkgCache::Flag::NotSource) == pkgCache::Flag::NotSource)
{
pkgTagSection Tags;
- TFRewriteData RW[] = {{"Status", NULL, NULL},{"Config-Version", NULL, NULL},{NULL, NULL, NULL}};
- const char *Zero = 0;
if (Tags.Scan(Buffer+Jitter,VF.Size+1) == false ||
- TFRewrite(stdout,Tags,&Zero,RW) == false)
+ Tags.Write(stdoutfd, NULL, RW) == false ||
+ stdoutfd.Write("\n", 1) == false)
{
_error->Error("Internal Error, Unable to parse a package record");
break;
}
- fputc('\n',stdout);
}
else
{
- if (fwrite(Buffer+Jitter,VF.Size+1,1,stdout) != 1)
+ if (stdoutfd.Write(Buffer + Jitter, VF.Size + 1) == false)
break;
}
-
+
Pos = VF.Offset + VF.Size;
}
- fflush(stdout);
if (_error->PendingError() == true)
break;
}
-
+
delete [] Buffer;
delete [] VFList;
return !_error->PendingError();
const char **Order = TFRewritePackageOrder;
if (Source == true)
Order = TFRewriteSourceOrder;
-
+
// Emit
+ FileFd stdoutfd;
+ stdoutfd.OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly, false);
unsigned char *Buffer = new unsigned char[Largest+1];
for (vector<PkgName>::iterator I = List.begin(); I != List.end(); ++I)
{
delete [] Buffer;
return false;
}
-
- Buffer[I->Length] = '\n';
+
+ Buffer[I->Length] = '\n';
if (Section.Scan((char *)Buffer,I->Length+1) == false)
{
delete [] Buffer;
}
// Sort the section
- if (TFRewrite(stdout,Section,Order,0) == false)
+ if (Section.Write(stdoutfd, Order) == false || stdoutfd.Write("\n", 1) == false)
{
delete [] Buffer;
return _error->Error("Internal error, failed to sort fields");
}
-
- fputc('\n',stdout);
}
-
+
delete [] Buffer;
return true;
}
PkgDone = true;
// Create a package writer object.
- PackagesWriter Packages(flCombine(CacheDir,BinCacheDB),
+ MultiCompress Comp(flCombine(ArchiveDir,PkgFile),
+ PkgCompress,Permissions);
+ PackagesWriter Packages(&Comp.Input, flCombine(CacheDir,BinCacheDB),
flCombine(OverrideDir,BinOverride),
flCombine(OverrideDir,ExtraOverride),
Arch);
Packages.Stats.DeLinkBytes = Stats.DeLinkBytes;
Packages.DeLinkLimit = DeLinkLimit;
- // Create a compressor object
- MultiCompress Comp(flCombine(ArchiveDir,PkgFile),
- PkgCompress,Permissions);
- Packages.Output = Comp.Input;
if (_error->PendingError() == true)
return _error->Error(_("Error processing directory %s"),BaseDir.c_str());
SrcDone = true;
// Create a package writer object.
- SourcesWriter Sources(flCombine(CacheDir, SrcCacheDB),
+ MultiCompress Comp(flCombine(ArchiveDir,SrcFile),
+ SrcCompress,Permissions);
+ SourcesWriter Sources(&Comp.Input, flCombine(CacheDir, SrcCacheDB),
flCombine(OverrideDir,BinOverride),
flCombine(OverrideDir,SrcOverride),
flCombine(OverrideDir,SrcExtraOverride));
Sources.DeLinkLimit = DeLinkLimit;
Sources.Stats.DeLinkBytes = Stats.DeLinkBytes;
-
- // Create a compressor object
- MultiCompress Comp(flCombine(ArchiveDir,SrcFile),
- SrcCompress,Permissions);
- Sources.Output = Comp.Input;
+
if (_error->PendingError() == true)
return _error->Error(_("Error processing directory %s"),BaseDir.c_str());
gettimeofday(&StartTime,0);
// Create a package writer object.
- ContentsWriter Contents("", Arch);
+ MultiCompress Comp(flCombine(ArchiveDir,this->Contents),
+ CntCompress,Permissions);
+ Comp.UpdateMTime = Setup.FindI("Default::ContentsAge",10)*24*60*60;
+ ContentsWriter Contents(&Comp.Input, "", Arch);
if (PkgExt.empty() == false && Contents.SetExts(PkgExt) == false)
return _error->Error(_("Package extension list is too long"));
if (_error->PendingError() == true)
return false;
- MultiCompress Comp(flCombine(ArchiveDir,this->Contents),
- CntCompress,Permissions);
- Comp.UpdateMTime = Setup.FindI("Default::ContentsAge",10)*24*60*60;
- Contents.Output = Comp.Input;
if (_error->PendingError() == true)
return false;
FileFd Head(flCombine(OverrideDir,ContentsHead),FileFd::ReadOnly);
if (_error->PendingError() == true)
return false;
-
+
unsigned long long Size = Head.Size();
unsigned char Buf[4096];
while (Size != 0)
unsigned long long ToRead = Size;
if (Size > sizeof(Buf))
ToRead = sizeof(Buf);
-
+
if (Head.Read(Buf,ToRead) == false)
return false;
-
- if (fwrite(Buf,1,ToRead,Comp.Input) != ToRead)
+
+ if (Comp.Input.Write(Buf, ToRead) == false)
return _error->Errno("fwrite",_("Error writing header to contents file"));
-
+
Size -= ToRead;
- }
- }
-
+ }
+ }
+
/* Go over all the package file records and parse all the package
files associated with this contents file into one great big honking
memory structure, then dump the sorted version */
Override = CmdL.FileList[2];
// Create a package writer object.
- PackagesWriter Packages(_config->Find("APT::FTPArchive::DB"),
+ PackagesWriter Packages(NULL, _config->Find("APT::FTPArchive::DB"),
Override, "", _config->Find("APT::FTPArchive::Architecture"));
if (_error->PendingError() == true)
return false;
return ShowHelp(CmdL);
// Create a package writer object.
- ContentsWriter Contents(_config->Find("APT::FTPArchive::DB"), _config->Find("APT::FTPArchive::Architecture"));
+ ContentsWriter Contents(NULL, _config->Find("APT::FTPArchive::DB"), _config->Find("APT::FTPArchive::Architecture"));
if (_error->PendingError() == true)
return false;
SOverride.c_str());
// Create a package writer object.
- SourcesWriter Sources(_config->Find("APT::FTPArchive::DB"),Override,SOverride);
+ SourcesWriter Sources(NULL, _config->Find("APT::FTPArchive::DB"),Override,SOverride);
if (_error->PendingError() == true)
return false;
string Dir = CmdL.FileList[1];
- ReleaseWriter Release("");
+ ReleaseWriter Release(NULL, "");
Release.DirStrip = Dir;
if (_error->PendingError() == true)
#include <apt-pkg/debfile.h>
#include <apt-pkg/dirstream.h>
#include <apt-pkg/error.h>
+#include <apt-pkg/fileutl.h>
#include <stdio.h>
#include <stdlib.h>
// GenContents::WriteSpace - Write a given number of white space chars /*{{{*/
// ---------------------------------------------------------------------
/* We mod 8 it and write tabs where possible. */
-void GenContents::WriteSpace(FILE *Out,unsigned int Current,unsigned int Target)
+void GenContents::WriteSpace(std::string &out, size_t Current, size_t Target)
{
if (Target <= Current)
Target = Current + 1;
-
+
/* Now we write tabs so long as the next tab stop would not pass
the target */
for (; (Current/8 + 1)*8 < Target; Current = (Current/8 + 1)*8)
- fputc('\t',Out);
+ out.append("\t");
// Fill the last bit with spaces
for (; Current < Target; Current++)
- fputc(' ',Out);
+ out.append(" ");
}
/*}}}*/
// GenContents::Print - Display the tree /*{{{*/
calls itself and runs over each section of the tree printing out
the pathname and the hit packages. We use Buf to build the pathname
summed over all the directory parents of this node. */
-void GenContents::Print(FILE *Out)
+void GenContents::Print(FileFd &Out)
{
char Buffer[1024];
Buffer[0] = 0;
DoPrint(Out,&Root,Buffer);
}
-void GenContents::DoPrint(FILE *Out,GenContents::Node *Top, char *Buf)
+void GenContents::DoPrint(FileFd &Out,GenContents::Node *Top, char *Buf)
{
if (Top == 0)
return;
if (Top->Path != 0)
{
strcat(Buf,Top->Path);
-
+
// Do not show the item if it is a directory with dups
if (Top->Path[strlen(Top->Path)-1] != '/' /*|| Top->Dups == 0*/)
{
- fputs(Buf,Out);
- WriteSpace(Out,strlen(Buf),60);
+ std::string out = Buf;
+ WriteSpace(out, out.length(), 60);
for (Node *I = Top; I != 0; I = I->Dups)
{
if (I != Top)
- fputc(',',Out);
- fputs(I->Package,Out);
+ out.append(",");
+ out.append(I->Package);
}
- fputc('\n',Out);
- }
- }
-
+ out.append("\n");
+ Out.Write(out.c_str(), out.length());
+ }
+ }
+
// Go along the directory link
DoPrint(Out,Top->DirDown,Buf);
*OldEnd = 0;
-
+
// Go right
DoPrint(Out,Top->BTreeRight,Buf);
}
#include <string>
class debDebFile;
+class FileFd;
class GenContents
{
unsigned long NodeLeft;
Node *Grab(Node *Top,const char *Name,const char *Package);
- void WriteSpace(FILE *Out,unsigned int Current,unsigned int Target);
- void DoPrint(FILE *Out,Node *Top, char *Buf);
+ void WriteSpace(std::string &out, size_t Current, size_t Target);
+ void DoPrint(FileFd &Out,Node *Top, char *Buf);
public:
char *Mystrdup(const char *From);
void Add(const char *Dir,const char *Package);
- void Print(FILE *Out);
+ void Print(FileFd &Out);
GenContents() : BlockList(0), StrPool(0), StrLeft(0),
NodePool(0), NodeLeft(0) {};
{
Outputs = 0;
Outputter = -1;
- Input = 0;
UpdateMTime = 0;
/* Parse the compression string, a space separated lists of compresison
};
close(Pipe[0]);
- Input = fdopen(Pipe[1],"w");
- if (Input == 0)
- return _error->Errno("fdopen",_("Failed to create FILE*"));
-
+ if (Input.OpenDescriptor(Pipe[1], FileFd::WriteOnly, true) == false)
+ return false;
+
if (Outputter == -1)
- return _error->Errno("fork",_("Failed to fork"));
+ return _error->Errno("fork",_("Failed to fork"));
return true;
}
/*}}}*/
/* */
bool MultiCompress::Die()
{
- if (Input == 0)
+ if (Input.IsOpen() == false)
return true;
-
- fclose(Input);
- Input = 0;
+
+ Input.Close();
bool Res = ExecWait(Outputter,_("Compress child"),false);
Outputter = -1;
return Res;
bool MultiCompress::Finalize(unsigned long long &OutSize)
{
OutSize = 0;
- if (Input == 0 || Die() == false)
+ if (Input.IsOpen() == false || Die() == false)
return false;
time_t Now;
public:
// The FD to write to for compression.
- FILE *Input;
+ FileFd Input;
unsigned long UpdateMTime;
bool Finalize(unsigned long long &OutSize);
using namespace std;
FTWScanner *FTWScanner::Owner;
-// SetTFRewriteData - Helper for setting rewrite lists /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-static inline TFRewriteData SetTFRewriteData(const char *tag,
- const char *rewrite,
- const char *newtag = 0)
-{
- TFRewriteData tfrd;
- tfrd.Tag = tag;
- tfrd.Rewrite = rewrite;
- tfrd.NewTag = newtag;
- return tfrd;
-}
- /*}}}*/
// ConfigToDoHashes - which hashes to generate /*{{{*/
static void SingleConfigToDoHashes(unsigned int &DoHashes, std::string const &Conf, unsigned int const Flag)
{
// FTWScanner::FTWScanner - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
-FTWScanner::FTWScanner(string const &Arch): Arch(Arch), DoHashes(~0)
+FTWScanner::FTWScanner(FileFd * const GivenOutput, string const &Arch): Arch(Arch), DoHashes(~0)
{
+ if (GivenOutput == NULL)
+ {
+ Output = new FileFd;
+ Output->OpenDescriptor(STDOUT_FILENO, FileFd::WriteOnly, false);
+ }
+ else
+ Output = GivenOutput;
ErrorPrinted = false;
NoLinkAct = !_config->FindB("APT::FTPArchive::DeLinkAct",true);
ConfigToDoHashes(DoHashes, "APT::FTPArchive");
// PackagesWriter::PackagesWriter - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
-PackagesWriter::PackagesWriter(string const &DB,string const &Overrides,string const &ExtOverrides,
+PackagesWriter::PackagesWriter(FileFd * const GivenOutput, string const &DB,string const &Overrides,string const &ExtOverrides,
string const &Arch) :
- FTWScanner(Arch), Db(DB), Stats(Db.Stats), TransWriter(NULL)
+ FTWScanner(GivenOutput, Arch), Db(DB), Stats(Db.Stats), TransWriter(NULL)
{
- Output = stdout;
SetExts(".deb .udeb");
DeLinkLimit = 0;
}
// This lists all the changes to the fields we are going to make.
- std::vector<TFRewriteData> Changes;
+ std::vector<pkgTagSection::Tag> Changes;
std::string Size;
strprintf(Size, "%llu", (unsigned long long) FileSize);
- Changes.push_back(SetTFRewriteData("Size", Size.c_str()));
+ Changes.push_back(pkgTagSection::Tag::Rewrite("Size", Size));
for (HashStringList::const_iterator hs = Db.HashesList.begin(); hs != Db.HashesList.end(); ++hs)
{
if (hs->HashType() == "MD5Sum")
- Changes.push_back(SetTFRewriteData("MD5sum", hs->HashValue().c_str()));
+ Changes.push_back(pkgTagSection::Tag::Rewrite("MD5sum", hs->HashValue()));
else if (hs->HashType() == "Checksum-FileSize")
continue;
else
- Changes.push_back(SetTFRewriteData(hs->HashType().c_str(), hs->HashValue().c_str()));
+ Changes.push_back(pkgTagSection::Tag::Rewrite(hs->HashType(), hs->HashValue()));
}
- Changes.push_back(SetTFRewriteData("Filename", NewFileName.c_str()));
- Changes.push_back(SetTFRewriteData("Priority", OverItem->Priority.c_str()));
- Changes.push_back(SetTFRewriteData("Status", 0));
- Changes.push_back(SetTFRewriteData("Optional", 0));
+ Changes.push_back(pkgTagSection::Tag::Rewrite("Filename", NewFileName));
+ Changes.push_back(pkgTagSection::Tag::Rewrite("Priority", OverItem->Priority));
+ Changes.push_back(pkgTagSection::Tag::Remove("Status"));
+ Changes.push_back(pkgTagSection::Tag::Remove("Optional"));
string DescriptionMd5;
if (LongDescription == false) {
MD5Summation descmd5;
descmd5.Add(desc.c_str());
DescriptionMd5 = descmd5.Result().Value();
- Changes.push_back(SetTFRewriteData("Description-md5", DescriptionMd5.c_str()));
+ Changes.push_back(pkgTagSection::Tag::Rewrite("Description-md5", DescriptionMd5));
if (TransWriter != NULL)
TransWriter->DoPackage(Package, desc, DescriptionMd5);
}
}
if (NewMaint.empty() == false)
- Changes.push_back(SetTFRewriteData("Maintainer", NewMaint.c_str()));
+ Changes.push_back(pkgTagSection::Tag::Rewrite("Maintainer", NewMaint));
/* Get rid of the Optional tag. This is an ugly, ugly, ugly hack that
dpkg-scanpackages does. Well sort of. dpkg-scanpackages just does renaming
{
if (Tags.FindS("Suggests").empty() == false)
OptionalStr = Tags.FindS("Suggests") + ", " + OptionalStr;
- Changes.push_back(SetTFRewriteData("Suggests", OptionalStr.c_str()));
+ Changes.push_back(pkgTagSection::Tag::Rewrite("Suggests", OptionalStr));
}
for (map<string,string>::const_iterator I = OverItem->FieldOverride.begin();
I != OverItem->FieldOverride.end(); ++I)
- Changes.push_back(SetTFRewriteData(I->first.c_str(),I->second.c_str()));
-
- Changes.push_back(SetTFRewriteData( 0, 0));
+ Changes.push_back(pkgTagSection::Tag::Rewrite(I->first, I->second));
// Rewrite and store the fields.
- if (TFRewrite(Output,Tags,TFRewritePackageOrder,Changes.data()) == false)
+ if (Tags.Write(*Output, TFRewritePackageOrder, Changes) == false ||
+ Output->Write("\n", 1) == false)
return false;
- fprintf(Output,"\n");
return Db.Finish();
}
// ---------------------------------------------------------------------
/* Create a Translation-Master file for this Packages file */
TranslationWriter::TranslationWriter(string const &File, string const &TransCompress,
- mode_t const &Permissions) : Output(NULL),
- RefCounter(0)
+ mode_t const &Permissions) : RefCounter(0)
{
if (File.empty() == true)
return;
Comp = new MultiCompress(File, TransCompress, Permissions);
- Output = Comp->Input;
+ Output = &Comp->Input;
}
/*}}}*/
// TranslationWriter::DoPackage - Process a single package /*{{{*/
if (Included.find(Record) != Included.end())
return true;
- fprintf(Output, "Package: %s\nDescription-md5: %s\nDescription-en: %s\n",
+ std::string out;
+ strprintf(out, "Package: %s\nDescription-md5: %s\nDescription-en: %s\n",
Pkg.c_str(), MD5.c_str(), Desc.c_str());
+ Output->Write(out.c_str(), out.length());
Included.insert(Record);
return true;
// SourcesWriter::SourcesWriter - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
-SourcesWriter::SourcesWriter(string const &DB, string const &BOverrides,string const &SOverrides,
+SourcesWriter::SourcesWriter(FileFd * const GivenOutput, string const &DB, string const &BOverrides,string const &SOverrides,
string const &ExtOverrides) :
- Db(DB), Stats(Db.Stats)
+ FTWScanner(GivenOutput), Db(DB), Stats(Db.Stats)
{
- Output = stdout;
AddPattern("*.dsc");
DeLinkLimit = 0;
Buffer = 0;
}
/*}}}*/
// SourcesWriter::DoPackage - Process a single package /*{{{*/
-static std::ostream& addDscHash(std::ostream &out, unsigned int const DoHashes,
+static std::string getDscHash(unsigned int const DoHashes,
Hashes::SupportedHashes const DoIt, pkgTagSection &Tags, char const * const FieldName,
HashString const * const Hash, unsigned long long Size, std::string FileName)
{
if ((DoHashes & DoIt) != DoIt || Tags.Exists(FieldName) == false || Hash == NULL)
- return out;
+ return "";
+ std::ostringstream out;
out << "\n " << Hash->HashValue() << " " << Size << " " << FileName
<< "\n " << Tags.FindS(FieldName);
- return out;
+ return out.str();
}
bool SourcesWriter::DoPackage(string FileName)
{
// Add the dsc to the files hash list
string const strippedName = flNotDir(FileName);
- std::ostringstream ostreamFiles;
- addDscHash(ostreamFiles, DoHashes, Hashes::MD5SUM, Tags, "Files", Db.HashesList.find("MD5Sum"), St.st_size, strippedName);
- string const Files = ostreamFiles.str();
-
- std::ostringstream ostreamSha1;
- addDscHash(ostreamSha1, DoHashes, Hashes::SHA1SUM, Tags, "Checksums-Sha1", Db.HashesList.find("SHA1"), St.st_size, strippedName);
- std::ostringstream ostreamSha256;
- addDscHash(ostreamSha256, DoHashes, Hashes::SHA256SUM, Tags, "Checksums-Sha256", Db.HashesList.find("SHA256"), St.st_size, strippedName);
- std::ostringstream ostreamSha512;
- addDscHash(ostreamSha512, DoHashes, Hashes::SHA512SUM, Tags, "Checksums-Sha512", Db.HashesList.find("SHA512"), St.st_size, strippedName);
+ std::string const Files = getDscHash(DoHashes, Hashes::MD5SUM, Tags, "Files", Db.HashesList.find("MD5Sum"), St.st_size, strippedName);
+ std::string ChecksumsSha1 = getDscHash(DoHashes, Hashes::SHA1SUM, Tags, "Checksums-Sha1", Db.HashesList.find("SHA1"), St.st_size, strippedName);
+ std::string ChecksumsSha256 = getDscHash(DoHashes, Hashes::SHA256SUM, Tags, "Checksums-Sha256", Db.HashesList.find("SHA256"), St.st_size, strippedName);
+ std::string ChecksumsSha512 = getDscHash(DoHashes, Hashes::SHA512SUM, Tags, "Checksums-Sha512", Db.HashesList.find("SHA512"), St.st_size, strippedName);
// Strip the DirStrip prefix from the FileName and add the PathPrefix
string NewFileName;
char *RealPath = NULL;
for (;isspace(*C); C++);
while (*C != 0)
- {
+ {
// Parse each of the elements
if (ParseQuoteWord(C,ParseJnk) == false ||
ParseQuoteWord(C,ParseJnk) == false ||
if (hs->HashType() == "MD5Sum" || hs->HashType() == "Checksum-FileSize")
continue;
char const * fieldname;
- std::ostream * out;
+ std::string * out;
if (hs->HashType() == "SHA1")
{
fieldname = "Checksums-Sha1";
- out = &ostreamSha1;
+ out = &ChecksumsSha1;
}
else if (hs->HashType() == "SHA256")
{
fieldname = "Checksums-Sha256";
- out = &ostreamSha256;
+ out = &ChecksumsSha256;
}
else if (hs->HashType() == "SHA512")
{
fieldname = "Checksums-Sha512";
- out = &ostreamSha512;
+ out = &ChecksumsSha512;
}
else
{
}
if (Tags.Exists(fieldname) == true)
continue;
- (*out) << "\n " << hs->HashValue() << " " << Db.GetFileSize() << " " << ParseJnk;
+ std::ostringstream streamout;
+ streamout << "\n " << hs->HashValue() << " " << Db.GetFileSize() << " " << ParseJnk;
+ out->append(streamout.str());
}
- // write back the GetFileInfo() stats data
+ // write back the GetFileInfo() stats data
Db.Finish();
}
if (Directory.length() > 2)
Directory.erase(Directory.end()-1);
- string const ChecksumsSha1 = ostreamSha1.str();
- string const ChecksumsSha256 = ostreamSha256.str();
- string const ChecksumsSha512 = ostreamSha512.str();
-
// This lists all the changes to the fields we are going to make.
// (5 hardcoded + checksums + maintainer + end marker)
- std::vector<TFRewriteData> Changes;
+ std::vector<pkgTagSection::Tag> Changes;
- Changes.push_back(SetTFRewriteData("Source", 0));
- Changes.push_back(SetTFRewriteData("Package",Package.c_str()));
+ Changes.push_back(pkgTagSection::Tag::Remove("Source"));
+ Changes.push_back(pkgTagSection::Tag::Rewrite("Package", Package));
if (Files.empty() == false)
- Changes.push_back(SetTFRewriteData("Files",Files.c_str()));
+ Changes.push_back(pkgTagSection::Tag::Rewrite("Files", Files));
if (ChecksumsSha1.empty() == false)
- Changes.push_back(SetTFRewriteData("Checksums-Sha1",ChecksumsSha1.c_str()));
+ Changes.push_back(pkgTagSection::Tag::Rewrite("Checksums-Sha1", ChecksumsSha1));
if (ChecksumsSha256.empty() == false)
- Changes.push_back(SetTFRewriteData("Checksums-Sha256",ChecksumsSha256.c_str()));
+ Changes.push_back(pkgTagSection::Tag::Rewrite("Checksums-Sha256", ChecksumsSha256));
if (ChecksumsSha512.empty() == false)
- Changes.push_back(SetTFRewriteData("Checksums-Sha512",ChecksumsSha512.c_str()));
+ Changes.push_back(pkgTagSection::Tag::Rewrite("Checksums-Sha512", ChecksumsSha512));
if (Directory != "./")
- Changes.push_back(SetTFRewriteData("Directory",Directory.c_str()));
- Changes.push_back(SetTFRewriteData("Priority",BestPrio.c_str()));
- Changes.push_back(SetTFRewriteData("Status",0));
+ Changes.push_back(pkgTagSection::Tag::Rewrite("Directory", Directory));
+ Changes.push_back(pkgTagSection::Tag::Rewrite("Priority", BestPrio));
+ Changes.push_back(pkgTagSection::Tag::Remove("Status"));
// Rewrite the maintainer field if necessary
bool MaintFailed;
- string NewMaint = OverItem->SwapMaint(Tags.FindS("Maintainer"),MaintFailed);
+ string NewMaint = OverItem->SwapMaint(Tags.FindS("Maintainer"), MaintFailed);
if (MaintFailed == true)
{
if (NoOverride == false)
{
- NewLine(1);
+ NewLine(1);
ioprintf(c1out, _(" %s maintainer is %s not %s\n"), Package.c_str(),
Tags.FindS("Maintainer").c_str(), OverItem->OldMaint.c_str());
- }
+ }
}
if (NewMaint.empty() == false)
- Changes.push_back(SetTFRewriteData("Maintainer", NewMaint.c_str()));
-
- for (map<string,string>::const_iterator I = SOverItem->FieldOverride.begin();
+ Changes.push_back(pkgTagSection::Tag::Rewrite("Maintainer", NewMaint.c_str()));
+
+ for (map<string,string>::const_iterator I = SOverItem->FieldOverride.begin();
I != SOverItem->FieldOverride.end(); ++I)
- Changes.push_back(SetTFRewriteData(I->first.c_str(),I->second.c_str()));
+ Changes.push_back(pkgTagSection::Tag::Rewrite(I->first, I->second));
- Changes.push_back(SetTFRewriteData(0, 0));
-
// Rewrite and store the fields.
- if (TFRewrite(Output,Tags,TFRewriteSourceOrder,Changes.data()) == false)
+ if (Tags.Write(*Output, TFRewriteSourceOrder, Changes) == false ||
+ Output->Write("\n", 1) == false)
return false;
- fprintf(Output,"\n");
Stats.Packages++;
// ContentsWriter::ContentsWriter - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
-ContentsWriter::ContentsWriter(string const &DB, string const &Arch) :
- FTWScanner(Arch), Db(DB), Stats(Db.Stats)
+ContentsWriter::ContentsWriter(FileFd * const GivenOutput, string const &DB, string const &Arch) :
+ FTWScanner(GivenOutput, Arch), Db(DB), Stats(Db.Stats)
{
SetExts(".deb");
- Output = stdout;
}
/*}}}*/
// ContentsWriter::DoPackage - Process a single package /*{{{*/
// ReleaseWriter::ReleaseWriter - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
-ReleaseWriter::ReleaseWriter(string const &/*DB*/)
+ReleaseWriter::ReleaseWriter(FileFd * const GivenOutput, string const &/*DB*/) : FTWScanner(GivenOutput)
{
if (_config->FindB("APT::FTPArchive::Release::Default-Patterns", true) == true)
{
}
AddPatterns(_config->FindVector("APT::FTPArchive::Release::Patterns"));
- Output = stdout;
time_t const now = time(NULL);
setlocale(LC_TIME, "C");
if (Value == "")
continue;
- fprintf(Output, "%s: %s\n", (*I).first.c_str(), Value.c_str());
+ std::string const out = I->first + ": " + Value + "\n";
+ Output->Write(out.c_str(), out.length());
}
ConfigToDoHashes(DoHashes, "APT::FTPArchive::Release");
/*}}}*/
// ReleaseWriter::Finish - Output the checksums /*{{{*/
// ---------------------------------------------------------------------
-static void printChecksumTypeRecord(FILE * const Output, char const * const Type, map<string, ReleaseWriter::CheckSum> const &CheckSums)
+static void printChecksumTypeRecord(FileFd &Output, char const * const Type, map<string, ReleaseWriter::CheckSum> const &CheckSums)
{
- fprintf(Output, "%s:\n", Type);
- for(map<string,ReleaseWriter::CheckSum>::const_iterator I = CheckSums.begin();
- I != CheckSums.end(); ++I)
- {
- HashString const * const hs = I->second.Hashes.find(Type);
- if (hs == NULL)
- continue;
- fprintf(Output, " %s %16llu %s\n",
- hs->HashValue().c_str(),
- (*I).second.size,
- (*I).first.c_str());
- }
+ {
+ std::string out;
+ strprintf(out, "%s:\n", Type);
+ Output.Write(out.c_str(), out.length());
+ }
+ for(map<string,ReleaseWriter::CheckSum>::const_iterator I = CheckSums.begin();
+ I != CheckSums.end(); ++I)
+ {
+ HashString const * const hs = I->second.Hashes.find(Type);
+ if (hs == NULL)
+ continue;
+ std::string out;
+ strprintf(out, " %s %16llu %s\n",
+ hs->HashValue().c_str(),
+ (*I).second.size,
+ (*I).first.c_str());
+ Output.Write(out.c_str(), out.length());
+ }
}
void ReleaseWriter::Finish()
{
if ((DoHashes & Hashes::MD5SUM) == Hashes::MD5SUM)
- printChecksumTypeRecord(Output, "MD5Sum", CheckSums);
+ printChecksumTypeRecord(*Output, "MD5Sum", CheckSums);
if ((DoHashes & Hashes::SHA1SUM) == Hashes::SHA1SUM)
- printChecksumTypeRecord(Output, "SHA1", CheckSums);
+ printChecksumTypeRecord(*Output, "SHA1", CheckSums);
if ((DoHashes & Hashes::SHA256SUM) == Hashes::SHA256SUM)
- printChecksumTypeRecord(Output, "SHA256", CheckSums);
+ printChecksumTypeRecord(*Output, "SHA256", CheckSums);
if ((DoHashes & Hashes::SHA512SUM) == Hashes::SHA512SUM)
- printChecksumTypeRecord(Output, "SHA512", CheckSums);
+ printChecksumTypeRecord(*Output, "SHA512", CheckSums);
}
string Arch;
const char *OriginalPath;
bool ErrorPrinted;
-
+
// Stuff for the delinker
bool NoLinkAct;
-
+
static FTWScanner *Owner;
static int ScannerFTW(const char *File,const struct stat *sb,int Flag);
static int ScannerFile(const char *File, bool const &ReadLink);
{
c1out << endl;
ErrorPrinted = true;
- }
+ }
}
-
+
public:
+ FileFd *Output;
unsigned int DoHashes;
unsigned long DeLinkLimit;
void AddPattern(char const *Pattern) { Patterns.push_back(Pattern); };
void AddPatterns(std::vector<std::string> const &patterns) { Patterns.insert(Patterns.end(), patterns.begin(), patterns.end()); };
bool SetExts(string const &Vals);
-
- FTWScanner(string const &Arch = string());
+
+ FTWScanner(FileFd * const Output, string const &Arch = string());
virtual ~FTWScanner() {};
};
class TranslationWriter
{
MultiCompress *Comp;
- FILE *Output;
std::set<string> Included;
unsigned short RefCounter;
+ FileFd *Output;
public:
void IncreaseRefCounter() { ++RefCounter; };
bool DoPackage(string const &Pkg, string const &Desc, string const &MD5);
TranslationWriter(string const &File, string const &TransCompress, mode_t const &Permissions);
- TranslationWriter() : Comp(NULL), Output(NULL), RefCounter(0) {};
+ TranslationWriter() : Comp(NULL), RefCounter(0) {};
~TranslationWriter();
};
{
Override Over;
CacheDB Db;
-
+
public:
// Some flags
// General options
string PathPrefix;
string DirStrip;
- FILE *Output;
struct CacheDB::Stats &Stats;
TranslationWriter *TransWriter;
{return Over.ReadExtraOverride(File);};
virtual bool DoPackage(string FileName);
- PackagesWriter(string const &DB,
+ PackagesWriter(FileFd * const Output, string const &DB,
string const &Overrides,
string const &ExtOverrides = "",
string const &Arch = "");
class ContentsWriter : public FTWScanner
{
CacheDB Db;
-
+
GenContents Gen;
-
+
public:
// General options
- FILE *Output;
struct CacheDB::Stats &Stats;
string Prefix;
-
+
bool DoPackage(string FileName,string Package);
virtual bool DoPackage(string FileName)
{return DoPackage(FileName,string());};
bool ReadFromPkgs(string const &PkgFile,string const &PkgCompress);
- void Finish() {Gen.Print(Output);};
+ void Finish() {Gen.Print(*Output);};
inline bool ReadyDB(string const &DB) {return Db.ReadyDB(DB);};
-
- ContentsWriter(string const &DB, string const &Arch = string());
+
+ ContentsWriter(FileFd * const Output, string const &DB, string const &Arch = string());
virtual ~ContentsWriter() {};
};
Override SOver;
char *Buffer;
unsigned long long BufSize;
-
+
public:
bool NoOverride;
bool DoAlwaysStat;
-
+
// General options
string PathPrefix;
string DirStrip;
- FILE *Output;
struct CacheDB::Stats &Stats;
virtual bool DoPackage(string FileName);
- SourcesWriter(string const &DB,string const &BOverrides,string const &SOverrides,
+ SourcesWriter(FileFd * const Output, string const &DB,string const &BOverrides,string const &SOverrides,
string const &ExtOverrides=string());
virtual ~SourcesWriter() {free(Buffer);};
};
class ReleaseWriter : public FTWScanner
{
public:
- ReleaseWriter(string const &DB);
+ ReleaseWriter(FileFd * const Output, string const &DB);
virtual bool DoPackage(string FileName);
void Finish();
- FILE *Output;
// General options
string PathPrefix;
string DirStrip;
# note that we do not display Description-md5 with the "apt" cmd
# and also show some additional fields that are calculated
testsuccessequal "Package: foo
+Version: 1.0
Priority: optional
Section: other
-Installed-Size: 43.0 kB
Maintainer: Joe Sixpack <joe@example.org>
-Version: 1.0
+Installed-Size: 43.0 kB
Download-Size: unknown
APT-Manual-Installed: yes
APT-Sources: file:$APTARCHIVE/ unstable/main i386 Packages
return Path;
}
bool GetFile(std::string &/*Filename*/, unsigned long long &/*Size*/) { return false; }
- bool RewriteEntry(FILE * /*Target*/, std::string /*File*/) { return false; }
+ bool RewriteEntry(FileFd & /*Target*/, std::string const &/*File*/) { return false; }
const char *GetFileName() { return NULL; }
const char *Type() { return NULL; }
--- /dev/null
+#include <config.h>
+
+#include <apt-pkg/fileutl.h>
+#include <apt-pkg/tagfile.h>
+
+#include <string>
+#include <sstream>
+
+#include <gtest/gtest.h>
+
+#include "file-helpers.h"
+
+std::string packageValue = "aaaa";
+std::string typoValue = "aa\n"
+ " .\n"
+ " cc";
+std::string typoRawValue = "\n " + typoValue;
+std::string overrideValue = "1";
+/*
+ std::cerr << "FILECONTENT: »";
+ char buffer[3000];
+ while (fd.ReadLine(buffer, sizeof(buffer)))
+ std::cerr << buffer;
+ std::cerr << "«" << std::endl;;
+*/
+
+void setupTestcaseStart(FileFd &fd, pkgTagSection §ion, std::string &content)
+{
+ createTemporaryFile("writesection", fd, NULL, NULL);
+ content = "Package: " + packageValue + "\n"
+ "TypoA:\n " + typoValue + "\n"
+ "Override: " + overrideValue + "\n"
+ "Override-Backup: " + overrideValue + "\n"
+ "\n";
+ EXPECT_TRUE(section.Scan(content.c_str(), content.length(), true));
+ EXPECT_TRUE(section.Exists("Package"));
+ EXPECT_TRUE(section.Exists("TypoA"));
+ EXPECT_TRUE(section.Exists("Override"));
+ EXPECT_TRUE(section.Exists("Override-Backup"));
+ EXPECT_FALSE(section.Exists("TypoB"));
+ EXPECT_EQ(packageValue, section.FindS("Package"));
+ EXPECT_EQ(typoValue, section.FindS("TypoA"));
+ EXPECT_EQ(typoRawValue, section.FindRawS("TypoA"));
+ EXPECT_EQ(1, section.FindI("Override"));
+ EXPECT_EQ(1, section.FindI("Override-Backup"));
+ EXPECT_EQ(4, section.Count());
+}
+TEST(TagSectionTest,WriteUnmodified)
+{
+ FileFd fd;
+ pkgTagSection section;
+ std::string content;
+ setupTestcaseStart(fd, section, content);
+ EXPECT_TRUE(section.Write(fd));
+ EXPECT_TRUE(fd.Seek(0));
+ pkgTagFile tfile(&fd);
+ ASSERT_TRUE(tfile.Step(section));
+ EXPECT_TRUE(section.Exists("Package"));
+ EXPECT_TRUE(section.Exists("TypoA"));
+ EXPECT_TRUE(section.Exists("Override"));
+ EXPECT_TRUE(section.Exists("Override-Backup"));
+ EXPECT_FALSE(section.Exists("TypoB"));
+ EXPECT_EQ(packageValue, section.FindS("Package"));
+ EXPECT_EQ(typoValue, section.FindS("TypoA"));
+ EXPECT_EQ(1, section.FindI("Override"));
+ EXPECT_EQ(1, section.FindI("Override-Backup"));
+ EXPECT_EQ(4, section.Count());
+}
+TEST(TagSectionTest,WriteUnmodifiedOrder)
+{
+ FileFd fd;
+ pkgTagSection section;
+ std::string content;
+ setupTestcaseStart(fd, section, content);
+ char const * const order[] = { "Package", "TypoA", "Override", NULL };
+ EXPECT_TRUE(section.Write(fd, order));
+ EXPECT_TRUE(fd.Seek(0));
+ pkgTagFile tfile(&fd);
+ ASSERT_TRUE(tfile.Step(section));
+ EXPECT_TRUE(section.Exists("Package"));
+ EXPECT_TRUE(section.Exists("TypoA"));
+ EXPECT_TRUE(section.Exists("Override"));
+ EXPECT_TRUE(section.Exists("Override-Backup"));
+ EXPECT_FALSE(section.Exists("TypoB"));
+ EXPECT_EQ(packageValue, section.FindS("Package"));
+ EXPECT_EQ(typoValue, section.FindS("TypoA"));
+ EXPECT_EQ(1, section.FindI("Override"));
+ EXPECT_EQ(1, section.FindI("Override-Backup"));
+ EXPECT_EQ(4, section.Count());
+}
+TEST(TagSectionTest,WriteUnmodifiedOrderReversed)
+{
+ FileFd fd;
+ pkgTagSection section;
+ std::string content;
+ setupTestcaseStart(fd, section, content);
+ char const * const order[] = { "Override", "TypoA", "Package", NULL };
+ EXPECT_TRUE(section.Write(fd, order));
+ EXPECT_TRUE(fd.Seek(0));
+ pkgTagFile tfile(&fd);
+ ASSERT_TRUE(tfile.Step(section));
+ EXPECT_TRUE(section.Exists("Package"));
+ EXPECT_TRUE(section.Exists("TypoA"));
+ EXPECT_TRUE(section.Exists("Override"));
+ EXPECT_TRUE(section.Exists("Override-Backup"));
+ EXPECT_FALSE(section.Exists("TypoB"));
+ EXPECT_EQ(packageValue, section.FindS("Package"));
+ EXPECT_EQ(typoValue, section.FindS("TypoA"));
+ EXPECT_EQ(1, section.FindI("Override"));
+ EXPECT_EQ(1, section.FindI("Override-Backup"));
+ EXPECT_EQ(4, section.Count());
+}
+TEST(TagSectionTest,WriteUnmodifiedOrderNotAll)
+{
+ FileFd fd;
+ pkgTagSection section;
+ std::string content;
+ setupTestcaseStart(fd, section, content);
+ char const * const order[] = { "Override", NULL };
+ EXPECT_TRUE(section.Write(fd, order));
+ EXPECT_TRUE(fd.Seek(0));
+ pkgTagFile tfile(&fd);
+ ASSERT_TRUE(tfile.Step(section));
+ EXPECT_TRUE(section.Exists("Package"));
+ EXPECT_TRUE(section.Exists("TypoA"));
+ EXPECT_TRUE(section.Exists("Override"));
+ EXPECT_TRUE(section.Exists("Override-Backup"));
+ EXPECT_FALSE(section.Exists("TypoB"));
+ EXPECT_EQ(packageValue, section.FindS("Package"));
+ EXPECT_EQ(typoValue, section.FindS("TypoA"));
+ EXPECT_EQ(1, section.FindI("Override"));
+ EXPECT_EQ(1, section.FindI("Override-Backup"));
+ EXPECT_EQ(4, section.Count());
+}
+TEST(TagSectionTest,WriteNoOrderRename)
+{
+ FileFd fd;
+ pkgTagSection section;
+ std::string content;
+ setupTestcaseStart(fd, section, content);
+ std::vector<pkgTagSection::Tag> rewrite;
+ rewrite.push_back(pkgTagSection::Tag::Rename("TypoA", "TypoB"));
+ EXPECT_TRUE(section.Write(fd, NULL, rewrite));
+ EXPECT_TRUE(fd.Seek(0));
+ pkgTagFile tfile(&fd);
+ ASSERT_TRUE(tfile.Step(section));
+ EXPECT_TRUE(section.Exists("Package"));
+ EXPECT_FALSE(section.Exists("TypoA"));
+ EXPECT_TRUE(section.Exists("TypoB"));
+ EXPECT_TRUE(section.Exists("Override"));
+ EXPECT_TRUE(section.Exists("Override-Backup"));
+ EXPECT_EQ(packageValue, section.FindS("Package"));
+ EXPECT_EQ(typoValue, section.FindS("TypoB"));
+ EXPECT_EQ(1, section.FindI("Override"));
+ EXPECT_EQ(1, section.FindI("Override-Backup"));
+ EXPECT_EQ(4, section.Count());
+}
+TEST(TagSectionTest,WriteNoOrderRemove)
+{
+ FileFd fd;
+ pkgTagSection section;
+ std::string content;
+ setupTestcaseStart(fd, section, content);
+ std::vector<pkgTagSection::Tag> rewrite;
+ rewrite.push_back(pkgTagSection::Tag::Remove("TypoA"));
+ rewrite.push_back(pkgTagSection::Tag::Rewrite("Override", ""));
+ EXPECT_TRUE(section.Write(fd, NULL, rewrite));
+ EXPECT_TRUE(fd.Seek(0));
+ pkgTagFile tfile(&fd);
+ ASSERT_TRUE(tfile.Step(section));
+ EXPECT_TRUE(section.Exists("Package"));
+ EXPECT_FALSE(section.Exists("TypoA"));
+ EXPECT_FALSE(section.Exists("TypoB"));
+ EXPECT_FALSE(section.Exists("Override"));
+ EXPECT_TRUE(section.Exists("Override-Backup"));
+ EXPECT_EQ(packageValue, section.FindS("Package"));
+ EXPECT_EQ(2, section.Count());
+}
+TEST(TagSectionTest,WriteNoOrderRewrite)
+{
+ FileFd fd;
+ pkgTagSection section;
+ std::string content;
+ setupTestcaseStart(fd, section, content);
+ std::vector<pkgTagSection::Tag> rewrite;
+ rewrite.push_back(pkgTagSection::Tag::Rewrite("Override", "42"));
+ EXPECT_TRUE(section.Write(fd, NULL, rewrite));
+ EXPECT_TRUE(fd.Seek(0));
+ pkgTagFile tfile(&fd);
+ ASSERT_TRUE(tfile.Step(section));
+ EXPECT_TRUE(section.Exists("Package"));
+ EXPECT_TRUE(section.Exists("TypoA"));
+ EXPECT_FALSE(section.Exists("TypoB"));
+ EXPECT_TRUE(section.Exists("Override"));
+ EXPECT_TRUE(section.Exists("Override-Backup"));
+ EXPECT_EQ(packageValue, section.FindS("Package"));
+ EXPECT_EQ(42, section.FindI("Override"));
+ EXPECT_EQ(1, section.FindI("Override-Backup"));
+ EXPECT_EQ(4, section.Count());
+}
+TEST(TagSectionTest,WriteOrderRename)
+{
+ FileFd fd;
+ pkgTagSection section;
+ std::string content;
+ setupTestcaseStart(fd, section, content);
+ std::vector<pkgTagSection::Tag> rewrite;
+ rewrite.push_back(pkgTagSection::Tag::Rename("TypoA", "TypoB"));
+ char const * const order[] = { "Package", "TypoA", "Override", NULL };
+ EXPECT_TRUE(section.Write(fd, order, rewrite));
+ EXPECT_TRUE(fd.Seek(0));
+ pkgTagFile tfile(&fd);
+ ASSERT_TRUE(tfile.Step(section));
+ EXPECT_TRUE(section.Exists("Package"));
+ EXPECT_FALSE(section.Exists("TypoA"));
+ EXPECT_TRUE(section.Exists("TypoB"));
+ EXPECT_TRUE(section.Exists("Override"));
+ EXPECT_TRUE(section.Exists("Override-Backup"));
+ EXPECT_EQ(packageValue, section.FindS("Package"));
+ EXPECT_EQ(typoValue, section.FindS("TypoB"));
+ EXPECT_EQ(1, section.FindI("Override"));
+ EXPECT_EQ(1, section.FindI("Override-Backup"));
+ EXPECT_EQ(4, section.Count());
+}
+TEST(TagSectionTest,WriteOrderRemove)
+{
+ FileFd fd;
+ pkgTagSection section;
+ std::string content;
+ setupTestcaseStart(fd, section, content);
+ std::vector<pkgTagSection::Tag> rewrite;
+ rewrite.push_back(pkgTagSection::Tag::Remove("TypoA"));
+ rewrite.push_back(pkgTagSection::Tag::Rewrite("Override", ""));
+ char const * const order[] = { "Package", "TypoA", "Override", NULL };
+ EXPECT_TRUE(section.Write(fd, order, rewrite));
+ EXPECT_TRUE(fd.Seek(0));
+ pkgTagFile tfile(&fd);
+ ASSERT_TRUE(tfile.Step(section));
+ EXPECT_TRUE(section.Exists("Package"));
+ EXPECT_FALSE(section.Exists("TypoA"));
+ EXPECT_FALSE(section.Exists("TypoB"));
+ EXPECT_FALSE(section.Exists("Override"));
+ EXPECT_TRUE(section.Exists("Override-Backup"));
+ EXPECT_EQ(packageValue, section.FindS("Package"));
+ EXPECT_EQ(1, section.FindI("Override-Backup"));
+ EXPECT_EQ(2, section.Count());
+}
+TEST(TagSectionTest,WriteOrderRewrite)
+{
+ FileFd fd;
+ pkgTagSection section;
+ std::string content;
+ setupTestcaseStart(fd, section, content);
+ std::vector<pkgTagSection::Tag> rewrite;
+ rewrite.push_back(pkgTagSection::Tag::Rewrite("Override", "42"));
+ char const * const order[] = { "Package", "TypoA", "Override", NULL };
+ EXPECT_TRUE(section.Write(fd, order, rewrite));
+ EXPECT_TRUE(fd.Seek(0));
+ pkgTagFile tfile(&fd);
+ ASSERT_TRUE(tfile.Step(section));
+ EXPECT_TRUE(section.Exists("Package"));
+ EXPECT_TRUE(section.Exists("TypoA"));
+ EXPECT_FALSE(section.Exists("TypoB"));
+ EXPECT_TRUE(section.Exists("Override"));
+ EXPECT_TRUE(section.Exists("Override-Backup"));
+ EXPECT_EQ(packageValue, section.FindS("Package"));
+ EXPECT_EQ(42, section.FindI("Override"));
+ EXPECT_EQ(1, section.FindI("Override-Backup"));
+ EXPECT_EQ(4, section.Count());
+}