qsort(List,Count,sizeof(*List),PrioComp);
}
/*}}}*/
-// ListUpdate - update the cache files /*{{{*/
+// ListUpdate - construct Fetcher and update the cache files /*{{{*/
// ---------------------------------------------------------------------
/* This is a simple wrapper to update the cache. it will fetch stuff
* from the network (or any other sources defined in sources.list)
pkgSourceList &List,
int PulseInterval)
{
- pkgAcquire::RunResult res;
pkgAcquire Fetcher;
if (Fetcher.Setup(&Stat, _config->FindDir("Dir::State::Lists")) == false)
return false;
if (List.GetIndexes(&Fetcher) == false)
return false;
+ return AcquireUpdate(Fetcher, PulseInterval, true);
+}
+ /*}}}*/
+// AcquireUpdate - take Fetcher and update the cache files /*{{{*/
+// ---------------------------------------------------------------------
+/* This is a simple wrapper to update the cache with a provided acquire
+ * If you only need control over Status and the used SourcesList use
+ * ListUpdate method instead.
+ */
+bool AcquireUpdate(pkgAcquire &Fetcher, int const PulseInterval,
+ bool const RunUpdateScripts, bool const ListCleanup)
+{
// Run scripts
- RunScripts("APT::Update::Pre-Invoke");
-
- // check arguments
- if(PulseInterval>0)
+ if (RunUpdateScripts == true)
+ RunScripts("APT::Update::Pre-Invoke");
+
+ pkgAcquire::RunResult res;
+ if(PulseInterval > 0)
res = Fetcher.Run(PulseInterval);
else
res = Fetcher.Run();
// Clean out any old list files
// Keep "APT::Get::List-Cleanup" name for compatibility, but
// this is really a global option for the APT library now
- if (!TransientNetworkFailure && !Failed &&
+ if (!TransientNetworkFailure && !Failed && ListCleanup == true &&
(_config->FindB("APT::Get::List-Cleanup",true) == true &&
_config->FindB("APT::List-Cleanup",true) == true))
{
// Run the success scripts if all was fine
- if(!TransientNetworkFailure && !Failed)
- RunScripts("APT::Update::Post-Invoke-Success");
+ if (RunUpdateScripts == true)
+ {
+ if(!TransientNetworkFailure && !Failed)
+ RunScripts("APT::Update::Post-Invoke-Success");
- // Run the other scripts
- RunScripts("APT::Update::Post-Invoke");
+ // Run the other scripts
+ RunScripts("APT::Update::Post-Invoke");
+ }
return true;
}
/*}}}*/
bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Compressor const &compressor, unsigned long const Perms)
{
Close();
- d = new FileFdPrivate;
- d->openmode = Mode;
Flags = AutoClose;
if ((Mode & WriteOnly) != WriteOnly && (Mode & (Atomic | Create | Empty | Exclusive)) != 0)
bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, APT::Configuration::Compressor const &compressor, bool AutoClose)
{
Close();
- d = new FileFdPrivate;
- d->openmode = Mode;
Flags = (AutoClose) ? FileFd::AutoClose : 0;
iFd = Fd;
this->FileName = "";
}
bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::Compressor const &compressor)
{
- d->compressor = compressor;
if (compressor.Name == "." || compressor.Binary.empty() == true)
return true;
+
+ if (d == NULL)
+ {
+ d = new FileFdPrivate();
+ d->openmode = Mode;
+ d->compressor = compressor;
+ }
+
#ifdef HAVE_ZLIB
- else if (compressor.Name == "gzip")
+ if (compressor.Name == "gzip")
{
+ if (d->gz != NULL)
+ {
+ gzclose(d->gz);
+ d->gz = NULL;
+ }
if ((Mode & ReadWrite) == ReadWrite)
d->gz = gzdopen(iFd, "r+");
else if ((Mode & WriteOnly) == WriteOnly)
}
#endif
#ifdef HAVE_BZ2
- else if (compressor.Name == "bzip2")
+ if (compressor.Name == "bzip2")
{
+ if (d->bz2 != NULL)
+ {
+ BZ2_bzclose(d->bz2);
+ d->bz2 = NULL;
+ }
if ((Mode & ReadWrite) == ReadWrite)
d->bz2 = BZ2_bzdopen(iFd, "r+");
else if ((Mode & WriteOnly) == WriteOnly)
}
#endif
+ // collect zombies here in case we reopen
+ if (d->compressor_pid > 0)
+ ExecWait(d->compressor_pid, "FileFdCompressor", true);
if ((Mode & ReadWrite) == ReadWrite)
+ {
+ Flags |= Fail;
return _error->Error("ReadWrite mode is not supported for file %s", FileName.c_str());
+ }
bool const Comp = (Mode & WriteOnly) == WriteOnly;
- // Handle 'decompression' of empty files
if (Comp == false)
{
+ // Handle 'decompression' of empty files
struct stat Buf;
fstat(iFd, &Buf);
if (Buf.st_size == 0 && S_ISFIFO(Buf.st_mode) == false)
// We don't need the file open - instead let the compressor open it
// as he properly knows better how to efficiently read from 'his' file
if (FileName.empty() == false)
+ {
close(iFd);
+ iFd = -1;
+ }
}
// Create a data pipe
int Pipe[2] = {-1,-1};
if (pipe(Pipe) != 0)
+ {
+ Flags |= Fail;
return _error->Errno("pipe",_("Failed to create subprocess IPC"));
+ }
for (int J = 0; J != 2; J++)
SetCloseExec(Pipe[J],true);
close(Pipe[0]);
else
close(Pipe[1]);
- if (Comp == true || FileName.empty() == true)
+ if ((Comp == true || FileName.empty() == true) && d->compressed_fd != -1)
close(d->compressed_fd);
return true;
do
{
#ifdef HAVE_ZLIB
- if (d->gz != NULL)
+ if (d != NULL && d->gz != NULL)
Res = gzread(d->gz,To,Size);
else
#endif
#ifdef HAVE_BZ2
- if (d->bz2 != NULL)
+ if (d != NULL && d->bz2 != NULL)
Res = BZ2_bzread(d->bz2,To,Size);
else
#endif
continue;
Flags |= Fail;
#ifdef HAVE_ZLIB
- if (d->gz != NULL)
+ if (d != NULL && d->gz != NULL)
{
int err;
char const * const errmsg = gzerror(d->gz, &err);
}
#endif
#ifdef HAVE_BZ2
- if (d->bz2 != NULL)
+ if (d != NULL && d->bz2 != NULL)
{
int err;
char const * const errmsg = BZ2_bzerror(d->bz2, &err);
To = (char *)To + Res;
Size -= Res;
- d->seekpos += Res;
+ if (d != NULL)
+ d->seekpos += Res;
if (Actual != 0)
*Actual += Res;
}
{
*To = '\0';
#ifdef HAVE_ZLIB
- if (d->gz != NULL)
+ if (d != NULL && d->gz != NULL)
return gzgets(d->gz, To, Size);
#endif
do
{
#ifdef HAVE_ZLIB
- if (d->gz != NULL)
+ if (d != NULL && d->gz != NULL)
Res = gzwrite(d->gz,From,Size);
else
#endif
#ifdef HAVE_BZ2
- if (d->bz2 != NULL)
+ if (d != NULL && d->bz2 != NULL)
Res = BZ2_bzwrite(d->bz2,(void*)From,Size);
else
#endif
{
Flags |= Fail;
#ifdef HAVE_ZLIB
- if (d->gz != NULL)
+ if (d != NULL && d->gz != NULL)
{
int err;
char const * const errmsg = gzerror(d->gz, &err);
}
#endif
#ifdef HAVE_BZ2
- if (d->bz2 != NULL)
+ if (d != NULL && d->bz2 != NULL)
{
int err;
char const * const errmsg = BZ2_bzerror(d->bz2, &err);
From = (char *)From + Res;
Size -= Res;
- d->seekpos += Res;
+ if (d != NULL)
+ d->seekpos += Res;
}
while (Res > 0 && Size > 0);
/* */
bool FileFd::Seek(unsigned long long To)
{
- if (d->pipe == true
+ if (d != NULL && (d->pipe == true
#ifdef HAVE_BZ2
- || d->bz2 != NULL
+ || d->bz2 != NULL
#endif
- )
+ ))
{
// Our poor man seeking in pipes is costly, so try to avoid it
unsigned long long seekpos = Tell();
return Skip(To - seekpos);
if ((d->openmode & ReadOnly) != ReadOnly)
+ {
+ Flags |= Fail;
return _error->Error("Reopen is only implemented for read-only files!");
+ }
#ifdef HAVE_BZ2
if (d->bz2 != NULL)
BZ2_bzclose(d->bz2);
#endif
- close(iFd);
- iFd = 0;
+ if (iFd != -1)
+ close(iFd);
+ iFd = -1;
if (TemporaryFileName.empty() == false)
iFd = open(TemporaryFileName.c_str(), O_RDONLY);
else if (FileName.empty() == false)
if (lseek(d->compressed_fd, 0, SEEK_SET) != 0)
iFd = d->compressed_fd;
if (iFd <= 0)
+ {
+ Flags |= Fail;
return _error->Error("Reopen is not implemented for pipes opened with FileFd::OpenDescriptor()!");
+ }
}
if (OpenInternDescriptor(d->openmode, d->compressor) == false)
+ {
+ Flags |= Fail;
return _error->Error("Seek on file %s because it couldn't be reopened", FileName.c_str());
+ }
if (To != 0)
return Skip(To);
}
int res;
#ifdef HAVE_ZLIB
- if (d->gz)
+ if (d != NULL && d->gz)
res = gzseek(d->gz,To,SEEK_SET);
else
#endif
return _error->Error("Unable to seek to %llu", To);
}
- d->seekpos = To;
+ if (d != NULL)
+ d->seekpos = To;
return true;
}
/*}}}*/
/* */
bool FileFd::Skip(unsigned long long Over)
{
- if (d->pipe == true
+ if (d != NULL && (d->pipe == true
#ifdef HAVE_BZ2
- || d->bz2 != NULL
+ || d->bz2 != NULL
#endif
- )
+ ))
{
d->seekpos += Over;
char buffer[1024];
{
unsigned long long toread = std::min((unsigned long long) sizeof(buffer), Over);
if (Read(buffer, toread) == false)
+ {
+ Flags |= Fail;
return _error->Error("Unable to seek ahead %llu",Over);
+ }
Over -= toread;
}
return true;
int res;
#ifdef HAVE_ZLIB
- if (d->gz != NULL)
+ if (d != NULL && d->gz != NULL)
res = gzseek(d->gz,Over,SEEK_CUR);
else
#endif
Flags |= Fail;
return _error->Error("Unable to seek ahead %llu",Over);
}
- d->seekpos = res;
+ if (d != NULL)
+ d->seekpos = res;
return true;
}
bool FileFd::Truncate(unsigned long long To)
{
#if defined HAVE_ZLIB || defined HAVE_BZ2
- if (d->gz != NULL || d->bz2 != NULL)
+ if (d != NULL && (d->gz != NULL || d->bz2 != NULL))
{
Flags |= Fail;
return _error->Error("Truncating compressed files is not implemented (%s)", FileName.c_str());
// seeking around, but not all users of FileFd use always Seek() and co
// so d->seekpos isn't always true and we can just use it as a hint if
// we have nothing else, but not always as an authority…
- if (d->pipe == true
+ if (d != NULL && (d->pipe == true
#ifdef HAVE_BZ2
- || d->bz2 != NULL
+ || d->bz2 != NULL
#endif
- )
+ ))
return d->seekpos;
off_t Res;
#ifdef HAVE_ZLIB
- if (d->gz != NULL)
+ if (d != NULL && d->gz != NULL)
Res = gztell(d->gz);
else
#endif
Res = lseek(iFd,0,SEEK_CUR);
if (Res == (off_t)-1)
+ {
+ Flags |= Fail;
_error->Errno("lseek","Failed to determine the current file position");
- d->seekpos = Res;
+ }
+ if (d != NULL)
+ d->seekpos = Res;
return Res;
}
/*}}}*/
unsigned long long FileFd::FileSize()
{
struct stat Buf;
- if (d->pipe == false && fstat(iFd,&Buf) != 0)
+ if ((d == NULL || d->pipe == false) && fstat(iFd,&Buf) != 0)
+ {
+ Flags |= Fail;
return _error->Errno("fstat","Unable to determine the file size");
+ }
// for compressor pipes st_size is undefined and at 'best' zero
- if (d->pipe == true || S_ISFIFO(Buf.st_mode))
+ if ((d != NULL && d->pipe == true) || S_ISFIFO(Buf.st_mode))
{
// we set it here, too, as we get the info here for free
// in theory the Open-methods should take care of it already
- d->pipe = true;
+ if (d != NULL)
+ d->pipe = true;
if (stat(FileName.c_str(), &Buf) != 0)
+ {
+ Flags |= Fail;
return _error->Errno("stat","Unable to determine the file size");
+ }
}
return Buf.st_size;
// for compressor pipes st_size is undefined and at 'best' zero,
// so we 'read' the content and 'seek' back - see there
- if (d->pipe == true
+ if (d != NULL && (d->pipe == true
#ifdef HAVE_BZ2
- || (d->bz2 && size > 0)
+ || (d->bz2 && size > 0)
#endif
- )
+ ))
{
unsigned long long const oldSeek = Tell();
char ignore[1000];
// only check gzsize if we are actually a gzip file, just checking for
// "gz" is not sufficient as uncompressed files could be opened with
// gzopen in "direct" mode as well
- else if (d->gz && !gzdirect(d->gz) && size > 0)
+ else if (d != NULL && d->gz && !gzdirect(d->gz) && size > 0)
{
off_t const oldPos = lseek(iFd,0,SEEK_CUR);
/* unfortunately zlib.h doesn't provide a gzsize(), so we have to do
* bits of the file */
// FIXME: Size for gz-files is limited by 32bit… no largefile support
if (lseek(iFd, -4, SEEK_END) < 0)
- return _error->Errno("lseek","Unable to seek to end of gzipped file");
+ {
+ Flags |= Fail;
+ return _error->Errno("lseek","Unable to seek to end of gzipped file");
+ }
size = 0L;
if (read(iFd, &size, 4) != 4)
- return _error->Errno("read","Unable to read original size of gzipped file");
+ {
+ Flags |= Fail;
+ return _error->Errno("read","Unable to read original size of gzipped file");
+ }
#ifdef WORDS_BIGENDIAN
uint32_t tmp_size = size;
#endif
if (lseek(iFd, oldPos, SEEK_SET) < 0)
- return _error->Errno("lseek","Unable to seek in gzipped file");
+ {
+ Flags |= Fail;
+ return _error->Errno("lseek","Unable to seek in gzipped file");
+ }
return size;
}
time_t FileFd::ModificationTime()
{
struct stat Buf;
- if (d->pipe == false && fstat(iFd,&Buf) != 0)
+ if ((d == NULL || d->pipe == false) && fstat(iFd,&Buf) != 0)
{
+ Flags |= Fail;
_error->Errno("fstat","Unable to determine the modification time of file %s", FileName.c_str());
return 0;
}
// for compressor pipes st_size is undefined and at 'best' zero
- if (d->pipe == true || S_ISFIFO(Buf.st_mode))
+ if ((d != NULL && d->pipe == true) || S_ISFIFO(Buf.st_mode))
{
// we set it here, too, as we get the info here for free
// in theory the Open-methods should take care of it already
- d->pipe = true;
+ if (d != NULL)
+ d->pipe = true;
if (stat(FileName.c_str(), &Buf) != 0)
{
+ Flags |= Fail;
_error->Errno("fstat","Unable to determine the modification time of file %s", FileName.c_str());
return 0;
}
d = NULL;
}
+ if (Res == false)
+ Flags |= Fail;
return Res;
}
/*}}}*/
{
#ifdef _POSIX_SYNCHRONIZED_IO
if (fsync(iFd) != 0)
+ {
+ Flags |= Fail;
return _error->Errno("sync",_("Problem syncing the file"));
+ }
#endif
return true;
}