// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: indexcopy.cc,v 1.2 1999/09/03 05:46:48 jgg Exp $
+// $Id: indexcopy.cc,v 1.7 2001/03/13 05:23:42 jgg Exp $
/* ######################################################################
Index Copying - Aid for copying and verifying the index files
#include <unistd.h>
#include <sys/stat.h>
#include <stdio.h>
-#include <wait.h>
/*}}}*/
// IndexCopy::CopyPackages - Copy the package files from the CD /*{{{*/
}
// Wait for gzip to finish
- int Status;
- if (waitpid(Process,&Status,0) != Process)
- return _error->Errno("wait","Waiting for gzip failed");
- if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
+ if (ExecWait(Process,_config->Find("Dir::bin::gzip","gzip").c_str(),false) == false)
return _error->Error("gzip failed, perhaps the disk is full.");
+
Pkg.Seek(0);
}
- pkgTagFile Parser(Pkg);
+ pkgTagFile Parser(&Pkg);
if (_error->PendingError() == true)
return false;
// Open the output file
char S[400];
- sprintf(S,"cdrom:%s/%s%s",Name.c_str(),(*I).c_str() + CDROM.length(),
- GetFileName());
+ snprintf(S,sizeof(S),"cdrom:[%s]/%s%s",Name.c_str(),
+ (*I).c_str() + CDROM.length(),GetFileName());
string TargetF = _config->FindDir("Dir::State::lists") + "partial/";
TargetF += URItoFileName(S);
if (_config->FindB("APT::CDROM::NoAct",false) == true)
TargetF = "/dev/null";
- FileFd Target(TargetF,FileFd::WriteEmpty);
+ FileFd Target(TargetF,FileFd::WriteEmpty);
+ FILE *TargetFl = fdopen(dup(Target.Fd()),"w");
if (_error->PendingError() == true)
return false;
+ if (TargetFl == 0)
+ return _error->Errno("fdopen","Failed to reopen fd");
// Setup the progress meter
Progress.OverallProgress(CurrentSize,TotalSize,FileSize,
string File;
unsigned long Size;
if (GetFile(File,Size) == false)
+ {
+ fclose(TargetFl);
return false;
+ }
if (Chop != 0)
File = OrigPath + ChopDirs(File,Chop);
Packages++;
Hits++;
- // Copy it to the target package file
- if (Chop != 0 || Mangled == true)
+ if (RewriteEntry(TargetFl,File) == false)
{
- if (RewriteEntry(Target,File) == false)
- continue;
+ fclose(TargetFl);
+ return false;
}
- else
- {
- const char *Start;
- const char *Stop;
- Section.GetSection(Start,Stop);
- if (Target.Write(Start,Stop-Start) == false)
- return false;
- }
}
+ fclose(TargetFl);
if (Debug == true)
cout << " Processed by using Prefix '" << Prefix << "' and chop " << Chop << endl;
return _error->Errno("rename","Failed to rename");
// Copy the release file
- sprintf(S,"cdrom:%s/%sRelease",Name.c_str(),(*I).c_str() + CDROM.length());
+ snprintf(S,sizeof(S),"cdrom:[%s]/%sRelease",Name.c_str(),
+ (*I).c_str() + CDROM.length());
string TargetF = _config->FindDir("Dir::State::lists") + "partial/";
TargetF += URItoFileName(S);
if (FileExists(*I + "Release") == true)
// ---------------------------------------------------------------------
/* We look for things in dists/ notation and convert them to
<dist> <component> form otherwise it is left alone. This also strips
- the CD path. */
+ the CD path.
+
+ This implements a regex sort of like:
+ (.*)/dists/([^/]*)/(.*)/binary-*
+ ^ ^ ^- Component
+ | |-------- Distribution
+ |------------------- Path
+
+ It was deciced to use only a single word for dist (rather than say
+ unstable/non-us) to increase the chance that each CD gets a single
+ line in sources.list.
+ */
void IndexCopy::ConvertToSourceList(string CD,string &Path)
{
char S[300];
- sprintf(S,"binary-%s",_config->Find("Apt::Architecture").c_str());
+ snprintf(S,sizeof(S),"binary-%s",_config->Find("Apt::Architecture").c_str());
// Strip the cdrom base path
Path = string(Path,CD.length());
// Not a dists type.
if (stringcmp(Path.begin(),Path.begin()+strlen("dists/"),"dists/") != 0)
return;
-
+
// Isolate the dist
string::size_type Slash = strlen("dists/");
string::size_type Slash2 = Path.find('/',Slash + 1);
string Dist = string(Path,Slash,Slash2 - Slash);
// Isolate the component
- Slash = Path.find('/',Slash2+1);
- if (Slash == string::npos || Slash + 2 >= Path.length())
- return;
- string Comp = string(Path,Slash2+1,Slash - Slash2-1);
-
- // Verify the trailing binar - bit
- Slash2 = Path.find('/',Slash + 1);
- if (Slash == string::npos)
- return;
- string Binary = string(Path,Slash+1,Slash2 - Slash-1);
-
- if (Binary != S && Binary != "source")
+ Slash = Slash2;
+ for (unsigned I = 0; I != 10; I++)
+ {
+ Slash = Path.find('/',Slash+1);
+ if (Slash == string::npos || Slash + 2 >= Path.length())
+ return;
+ string Comp = string(Path,Slash2+1,Slash - Slash2-1);
+
+ // Verify the trailing binary- bit
+ string::size_type BinSlash = Path.find('/',Slash + 1);
+ if (Slash == string::npos)
+ return;
+ string Binary = string(Path,Slash+1,BinSlash - Slash-1);
+
+ if (Binary != S && Binary != "source")
+ continue;
+
+ Path = Dist + ' ' + Comp;
return;
-
- Path = Dist + ' ' + Comp;
+ }
}
/*}}}*/
// IndexCopy::GrabFirst - Return the first Depth path components /*{{{*/
return true;
}
/*}}}*/
-// IndexCopy::CopyWithReplace - Copy a section and replace text /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool IndexCopy::CopyWithReplace(FileFd &Target,const char *Tag,string New)
-{
- // Mangle the output filename
- const char *Start;
- const char *Stop;
- const char *Filename;
- Section->Find(Tag,Filename,Stop);
-
- /* We need to rewrite the filename field so we emit
- all fields except the filename file and rewrite that one */
- for (unsigned int I = 0; I != Section->Count(); I++)
- {
- Section->Get(Start,Stop,I);
- if (Start <= Filename && Stop > Filename)
- {
- char S[500];
- sprintf(S,"%s: %s\n",Tag,New.c_str());
- if (I + 1 == Section->Count())
- strcat(S,"\n");
- if (Target.Write(S,strlen(S)) == false)
- return false;
- }
- else
- {
- if (Target.Write(Start,Stop-Start) == false)
- return false;
- if (Stop[-1] != '\n')
- if (Target.Write("\n",1) == false)
- return false;
- }
- }
- if (Target.Write("\n",1) == false)
- return false;
-}
- /*}}}*/
// PackageCopy::GetFile - Get the file information from the section /*{{{*/
// ---------------------------------------------------------------------
/* */
// PackageCopy::RewriteEntry - Rewrite the entry with a new filename /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool PackageCopy::RewriteEntry(FileFd &Target,string File)
+bool PackageCopy::RewriteEntry(FILE *Target,string File)
{
- return CopyWithReplace(Target,"Filename",File);
+ TFRewriteData Changes[] = {{"Filename",File.c_str()},
+ {}};
+
+ if (TFRewrite(Target,*Section,TFRewritePackageOrder,Changes) == false)
+ return false;
+ fputc('\n',Target);
+ return true;
}
/*}}}*/
// SourceCopy::GetFile - Get the file information from the section /*{{{*/
if (Base.empty() == false && Base[Base.length()-1] != '/')
Base += '/';
- // Iterate over the entire list grabbing each triplet
+ // Read the first file triplet
const char *C = Files.c_str();
string sSize;
string MD5Hash;
// SourceCopy::RewriteEntry - Rewrite the entry with a new filename /*{{{*/
// ---------------------------------------------------------------------
/* */
-bool SourceCopy::RewriteEntry(FileFd &Target,string File)
+bool SourceCopy::RewriteEntry(FILE *Target,string File)
{
- return CopyWithReplace(Target,"Directory",
- string(File,0,File.rfind('/')));
+ string Dir(File,0,File.rfind('/'));
+ TFRewriteData Changes[] = {{"Directory",Dir.c_str()},
+ {}};
+
+ if (TFRewrite(Target,*Section,TFRewriteSourceOrder,Changes) == false)
+ return false;
+ fputc('\n',Target);
+ return true;
}
/*}}}*/