From: Michael Vogt Date: Fri, 14 Mar 2014 08:02:44 +0000 (+0100) Subject: fix test/integration/test-apt-helper X-Git-Tag: 0.9.16~2 X-Git-Url: https://git.saurik.com/apt.git/commitdiff_plain/83b880c6505a20247239d897b7387bba37942993?hp=-c fix test/integration/test-apt-helper --- 83b880c6505a20247239d897b7387bba37942993 diff --combined apt-pkg/contrib/fileutl.cc index 79bcf112c,26945c183..1eabf37f4 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@@ -1,6 -1,5 +1,5 @@@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ - // $Id: fileutl.cc,v 1.42 2002/09/14 05:29:22 jgg Exp $ /* ###################################################################### File Utilities @@@ -26,16 -25,22 +25,22 @@@ #include #include #include - + #include + + #include + #include + #include + #include + #include + #include + #include #include #include #include - #include #include #include #include - #include #include #include #include @@@ -52,6 -57,10 +57,10 @@@ #ifdef HAVE_BZ2 #include #endif + #ifdef HAVE_LZMA + #include + #include + #endif #ifdef WORDS_BIGENDIAN #include @@@ -62,54 -71,6 +71,6 @@@ using namespace std; - class FileFdPrivate { - public: - #ifdef HAVE_ZLIB - gzFile gz; - #else - void* gz; - #endif - #ifdef HAVE_BZ2 - BZFILE* bz2; - #else - void* bz2; - #endif - int compressed_fd; - pid_t compressor_pid; - bool pipe; - APT::Configuration::Compressor compressor; - unsigned int openmode; - unsigned long long seekpos; - FileFdPrivate() : gz(NULL), bz2(NULL), - compressed_fd(-1), compressor_pid(-1), pipe(false), - openmode(0), seekpos(0) {}; - bool CloseDown(std::string const &FileName) - { - bool Res = true; - #ifdef HAVE_ZLIB - if (gz != NULL) { - int const e = gzclose(gz); - gz = NULL; - // gzdclose() on empty files always fails with "buffer error" here, ignore that - if (e != 0 && e != Z_BUF_ERROR) - Res &= _error->Errno("close",_("Problem closing the gzip file %s"), FileName.c_str()); - } - #endif - #ifdef HAVE_BZ2 - if (bz2 != NULL) { - BZ2_bzclose(bz2); - bz2 = NULL; - } - #endif - if (compressor_pid > 0) - ExecWait(compressor_pid, "FileFdCompressor", true); - compressor_pid = -1; - - return Res; - } - ~FileFdPrivate() { CloseDown(""); } - }; - // RunScripts - Run a set of scripts from a configuration subtree /*{{{*/ // --------------------------------------------------------------------- /* */ @@@ -874,6 -835,122 +835,122 @@@ bool ExecWait(pid_t Pid,const char *Nam } /*}}}*/ + class FileFdPrivate { /*{{{*/ + public: + #ifdef HAVE_ZLIB + gzFile gz; + #endif + #ifdef HAVE_BZ2 + BZFILE* bz2; + #endif + #ifdef HAVE_LZMA + struct LZMAFILE { + FILE* file; + uint8_t buffer[4096]; + lzma_stream stream; + lzma_ret err; + bool eof; + bool compressing; + + LZMAFILE() : file(NULL), eof(false), compressing(false) {} + ~LZMAFILE() { + if (compressing == true) + { + for (;;) { + stream.avail_out = sizeof(buffer)/sizeof(buffer[0]); + stream.next_out = buffer; + err = lzma_code(&stream, LZMA_FINISH); + if (err != LZMA_OK && err != LZMA_STREAM_END) + { + _error->Error("~LZMAFILE: Compress finalisation failed"); + break; + } + size_t const n = sizeof(buffer)/sizeof(buffer[0]) - stream.avail_out; + if (n && fwrite(buffer, 1, n, file) != n) + { + _error->Errno("~LZMAFILE",_("Write error")); + break; + } + if (err == LZMA_STREAM_END) + break; + } + } + lzma_end(&stream); + fclose(file); + } + }; + LZMAFILE* lzma; + #endif + int compressed_fd; + pid_t compressor_pid; + bool pipe; + APT::Configuration::Compressor compressor; + unsigned int openmode; + unsigned long long seekpos; + FileFdPrivate() : + #ifdef HAVE_ZLIB + gz(NULL), + #endif + #ifdef HAVE_BZ2 + bz2(NULL), + #endif + #ifdef HAVE_LZMA + lzma(NULL), + #endif + compressed_fd(-1), compressor_pid(-1), pipe(false), + openmode(0), seekpos(0) {}; + bool InternalClose(std::string const &FileName) + { + if (false) + /* dummy so that the rest can be 'else if's */; + #ifdef HAVE_ZLIB + else if (gz != NULL) { + int const e = gzclose(gz); + gz = NULL; + // gzdclose() on empty files always fails with "buffer error" here, ignore that + if (e != 0 && e != Z_BUF_ERROR) + return _error->Errno("close",_("Problem closing the gzip file %s"), FileName.c_str()); + } + #endif + #ifdef HAVE_BZ2 + else if (bz2 != NULL) { + BZ2_bzclose(bz2); + bz2 = NULL; + } + #endif + #ifdef HAVE_LZMA + else if (lzma != NULL) { + delete lzma; + lzma = NULL; + } + #endif + return true; + } + bool CloseDown(std::string const &FileName) + { + bool const Res = InternalClose(FileName); + + if (compressor_pid > 0) + ExecWait(compressor_pid, "FileFdCompressor", true); + compressor_pid = -1; + + return Res; + } + bool InternalStream() const { + return false + #ifdef HAVE_BZ2 + || bz2 != NULL + #endif + #ifdef HAVE_LZMA + || lzma != NULL + #endif + ; + } + + + ~FileFdPrivate() { CloseDown(""); } + }; + /*}}}*/ // FileFd::Open - Open a file /*{{{*/ // --------------------------------------------------------------------- /* The most commonly used open mode combinations are given with Mode */ @@@ -891,7 -968,7 +968,7 @@@ bool FileFd::Open(string FileName,unsig { for (; compressor != compressors.end(); ++compressor) { - std::string file = std::string(FileName).append(compressor->Extension); + std::string file = FileName + compressor->Extension; if (FileExists(file) == false) continue; FileName = file; @@@ -1061,30 -1138,12 +1138,12 @@@ bool FileFd::OpenDescriptor(int Fd, uns { Close(); Flags = (AutoClose) ? FileFd::AutoClose : 0; - if (AutoClose == false && ( - #ifdef HAVE_ZLIB - compressor.Name == "gzip" || - #endif - #ifdef HAVE_BZ2 - compressor.Name == "bzip2" || - #endif - false)) - { - // Need to duplicate fd here or gzclose for cleanup will close the fd as well - iFd = dup(Fd); - } - else - iFd = Fd; + iFd = Fd; this->FileName = ""; - if (Fd == -1 || OpenInternDescriptor(Mode, compressor) == false) + if (OpenInternDescriptor(Mode, compressor) == false) { if (iFd != -1 && ( - #ifdef HAVE_ZLIB - compressor.Name == "gzip" || - #endif - #ifdef HAVE_BZ2 - compressor.Name == "bzip2" || - #endif + (Flags & Compressed) == Compressed || AutoClose == true)) { close (iFd); @@@ -1096,52 -1155,121 +1155,121 @@@ } bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::Compressor const &compressor) { + if (iFd == -1) + return false; if (compressor.Name == "." || compressor.Binary.empty() == true) return true; + #if defined HAVE_ZLIB || defined HAVE_BZ2 || defined HAVE_LZMA + // the API to open files is similar, so setup to avoid code duplicates later + // and while at it ensure that we close before opening (if its a reopen) + void* (*compress_open)(int, const char *) = NULL; + if (false) + /* dummy so that the rest can be 'else if's */; + #define APT_COMPRESS_INIT(NAME,OPEN) \ + else if (compressor.Name == NAME) \ + { \ + compress_open = (void*(*)(int, const char *)) OPEN; \ + if (d != NULL) d->InternalClose(FileName); \ + } + #ifdef HAVE_ZLIB + APT_COMPRESS_INIT("gzip", gzdopen) + #endif + #ifdef HAVE_BZ2 + APT_COMPRESS_INIT("bzip2", BZ2_bzdopen) + #endif + #ifdef HAVE_LZMA + APT_COMPRESS_INIT("xz", fdopen) + APT_COMPRESS_INIT("lzma", fdopen) + #endif + #undef APT_COMPRESS_INIT + #endif + if (d == NULL) { d = new FileFdPrivate(); d->openmode = Mode; d->compressor = compressor; + #if defined HAVE_ZLIB || defined HAVE_BZ2 || defined HAVE_LZMA + if (AutoClose == false && compress_open != NULL) + { + // Need to duplicate fd here or gz/bz2 close for cleanup will close the fd as well + int const internFd = dup(iFd); + if (internFd == -1) + return FileFdErrno("OpenInternDescriptor", _("Could not open file descriptor %d"), iFd); + iFd = internFd; + } + #endif } - #ifdef HAVE_ZLIB - if (compressor.Name == "gzip") + #if defined HAVE_ZLIB || defined HAVE_BZ2 || defined HAVE_LZMA + if (compress_open != NULL) { - if (d->gz != NULL) - { - gzclose(d->gz); - d->gz = NULL; - } + void* compress_struct = NULL; if ((Mode & ReadWrite) == ReadWrite) - d->gz = gzdopen(iFd, "r+"); + compress_struct = compress_open(iFd, "r+"); else if ((Mode & WriteOnly) == WriteOnly) - d->gz = gzdopen(iFd, "w"); + compress_struct = compress_open(iFd, "w"); else - d->gz = gzdopen(iFd, "r"); - if (d->gz == NULL) + compress_struct = compress_open(iFd, "r"); + if (compress_struct == NULL) return false; - Flags |= Compressed; - return true; - } + + if (false) + /* dummy so that the rest can be 'else if's */; + #ifdef HAVE_ZLIB + else if (compressor.Name == "gzip") + d->gz = (gzFile) compress_struct; #endif #ifdef HAVE_BZ2 - if (compressor.Name == "bzip2") - { - if (d->bz2 != NULL) + else if (compressor.Name == "bzip2") + d->bz2 = (BZFILE*) compress_struct; + #endif + #ifdef HAVE_LZMA + else if (compressor.Name == "xz" || compressor.Name == "lzma") { - BZ2_bzclose(d->bz2); - d->bz2 = NULL; + uint32_t const xzlevel = 6; + uint64_t const memlimit = UINT64_MAX; + if (d->lzma == NULL) + d->lzma = new FileFdPrivate::LZMAFILE; + d->lzma->file = (FILE*) compress_struct; + d->lzma->stream = LZMA_STREAM_INIT; + + if ((Mode & ReadWrite) == ReadWrite) + return FileFdError("ReadWrite mode is not supported for file %s", FileName.c_str()); + + if ((Mode & WriteOnly) == WriteOnly) + { + if (compressor.Name == "xz") + { + if (lzma_easy_encoder(&d->lzma->stream, xzlevel, LZMA_CHECK_CRC32) != LZMA_OK) + return false; + } + else + { + lzma_options_lzma options; + lzma_lzma_preset(&options, xzlevel); + if (lzma_alone_encoder(&d->lzma->stream, &options) != LZMA_OK) + return false; + } + d->lzma->compressing = true; + } + else + { + if (compressor.Name == "xz") + { + if (lzma_auto_decoder(&d->lzma->stream, memlimit, 0) != LZMA_OK) + return false; + } + else + { + if (lzma_alone_decoder(&d->lzma->stream, memlimit) != LZMA_OK) + return false; + } + d->lzma->compressing = false; + } } - if ((Mode & ReadWrite) == ReadWrite) - d->bz2 = BZ2_bzdopen(iFd, "r+"); - else if ((Mode & WriteOnly) == WriteOnly) - d->bz2 = BZ2_bzdopen(iFd, "w"); - else - d->bz2 = BZ2_bzdopen(iFd, "r"); - if (d->bz2 == NULL) - return false; + #endif Flags |= Compressed; return true; } @@@ -1198,7 -1326,7 +1326,7 @@@ } else { - if (FileName.empty() == true) + if (d->compressed_fd != -1) dup2(d->compressed_fd,STDIN_FILENO); dup2(Pipe[1],STDOUT_FILENO); } @@@ -1267,24 -1395,55 +1395,55 @@@ bool FileFd::Read(void *To,unsigned lon *((char *)To) = '\0'; do { + if (false) + /* dummy so that the rest can be 'else if's */; #ifdef HAVE_ZLIB - if (d != NULL && d->gz != NULL) + else if (d != NULL && d->gz != NULL) Res = gzread(d->gz,To,Size); - else #endif #ifdef HAVE_BZ2 - if (d != NULL && d->bz2 != NULL) + else if (d != NULL && d->bz2 != NULL) Res = BZ2_bzread(d->bz2,To,Size); - else #endif + #ifdef HAVE_LZMA + else if (d != NULL && d->lzma != NULL) + { + if (d->lzma->eof == true) + break; + + d->lzma->stream.next_out = (uint8_t *) To; + d->lzma->stream.avail_out = Size; + if (d->lzma->stream.avail_in == 0) + { + d->lzma->stream.next_in = d->lzma->buffer; + d->lzma->stream.avail_in = fread(d->lzma->buffer, 1, sizeof(d->lzma->buffer)/sizeof(d->lzma->buffer[0]), d->lzma->file); + } + d->lzma->err = lzma_code(&d->lzma->stream, LZMA_RUN); + if (d->lzma->err == LZMA_STREAM_END) + { + d->lzma->eof = true; + Res = Size - d->lzma->stream.avail_out; + } + else if (d->lzma->err != LZMA_OK) + { + Res = -1; + errno = 0; + } + else + Res = Size - d->lzma->stream.avail_out; + } + #endif + else Res = read(iFd,To,Size); if (Res < 0) { if (errno == EINTR) continue; + if (false) + /* dummy so that the rest can be 'else if's */; #ifdef HAVE_ZLIB - if (d != NULL && d->gz != NULL) + else if (d != NULL && d->gz != NULL) { int err; char const * const errmsg = gzerror(d->gz, &err); @@@ -1293,13 -1452,17 +1452,17 @@@ } #endif #ifdef HAVE_BZ2 - if (d != NULL && d->bz2 != NULL) + else if (d != NULL && d->bz2 != NULL) { int err; char const * const errmsg = BZ2_bzerror(d->bz2, &err); if (err != BZ_IO_ERROR) return FileFdError("BZ2_bzread: %s (%d: %s)", _("Read error"), err, errmsg); } + #endif + #ifdef HAVE_LZMA + else if (d != NULL && d->lzma != NULL) + return FileFdError("lzma_read: %s (%d)", _("Read error"), d->lzma->err); #endif return FileFdErrno("read",_("Read error")); } @@@ -1364,23 -1527,45 +1527,45 @@@ bool FileFd::Write(const void *From,uns errno = 0; do { + if (false) + /* dummy so that the rest can be 'else if's */; #ifdef HAVE_ZLIB - if (d != NULL && d->gz != NULL) - Res = gzwrite(d->gz,From,Size); - else + else if (d != NULL && d->gz != NULL) + Res = gzwrite(d->gz,From,Size); #endif #ifdef HAVE_BZ2 - if (d != NULL && d->bz2 != NULL) - Res = BZ2_bzwrite(d->bz2,(void*)From,Size); - else + else if (d != NULL && d->bz2 != NULL) + Res = BZ2_bzwrite(d->bz2,(void*)From,Size); + #endif + #ifdef HAVE_LZMA + else if (d != NULL && d->lzma != NULL) + { + d->lzma->stream.next_in = (uint8_t *)From; + d->lzma->stream.avail_in = Size; + d->lzma->stream.next_out = d->lzma->buffer; + d->lzma->stream.avail_out = sizeof(d->lzma->buffer)/sizeof(d->lzma->buffer[0]); + d->lzma->err = lzma_code(&d->lzma->stream, LZMA_RUN); + if (d->lzma->err != LZMA_OK) + return false; + size_t const n = sizeof(d->lzma->buffer)/sizeof(d->lzma->buffer[0]) - d->lzma->stream.avail_out; + size_t const m = (n == 0) ? 0 : fwrite(d->lzma->buffer, 1, n, d->lzma->file); + if (m != n) + Res = -1; + else + Res = Size - d->lzma->stream.avail_in; + } #endif - Res = write(iFd,From,Size); + else + Res = write(iFd,From,Size); + if (Res < 0 && errno == EINTR) continue; if (Res < 0) { + if (false) + /* dummy so that the rest can be 'else if's */; #ifdef HAVE_ZLIB - if (d != NULL && d->gz != NULL) + else if (d != NULL && d->gz != NULL) { int err; char const * const errmsg = gzerror(d->gz, &err); @@@ -1389,18 -1574,22 +1574,22 @@@ } #endif #ifdef HAVE_BZ2 - if (d != NULL && d->bz2 != NULL) + else if (d != NULL && d->bz2 != NULL) { int err; char const * const errmsg = BZ2_bzerror(d->bz2, &err); if (err != BZ_IO_ERROR) return FileFdError("BZ2_bzwrite: %s (%d: %s)", _("Write error"), err, errmsg); } + #endif + #ifdef HAVE_LZMA + else if (d != NULL && d->lzma != NULL) + return FileFdErrno("lzma_fwrite", _("Write error")); #endif return FileFdErrno("write",_("Write error")); } - From = (char *)From + Res; + From = (char const *)From + Res; Size -= Res; if (d != NULL) d->seekpos += Res; @@@ -1424,7 -1613,7 +1613,7 @@@ bool FileFd::Write(int Fd, const void * if (Res < 0) return _error->Errno("write",_("Write error")); - From = (char *)From + Res; + From = (char const *)From + Res; Size -= Res; } while (Res > 0 && Size > 0); @@@ -1440,11 -1629,7 +1629,7 @@@ /* */ bool FileFd::Seek(unsigned long long To) { - if (d != NULL && (d->pipe == true - #ifdef HAVE_BZ2 - || d->bz2 != NULL - #endif - )) + if (d != NULL && (d->pipe == true || d->InternalStream() == true)) { // Our poor man seeking in pipes is costly, so try to avoid it unsigned long long seekpos = Tell(); @@@ -1455,13 -1640,7 +1640,7 @@@ if ((d->openmode & ReadOnly) != ReadOnly) return FileFdError("Reopen is only implemented for read-only files!"); - #ifdef HAVE_BZ2 - if (d->bz2 != NULL) - { - BZ2_bzclose(d->bz2); - d->bz2 = NULL; - } - #endif + d->InternalClose(FileName); if (iFd != -1) close(iFd); iFd = -1; @@@ -1507,11 -1686,7 +1686,7 @@@ /* */ bool FileFd::Skip(unsigned long long Over) { - if (d != NULL && (d->pipe == true - #ifdef HAVE_BZ2 - || d->bz2 != NULL - #endif - )) + if (d != NULL && (d->pipe == true || d->InternalStream() == true)) { d->seekpos += Over; char buffer[1024]; @@@ -1548,8 -1723,12 +1723,12 @@@ bool FileFd::Truncate(unsigned long lon // truncating /dev/null is always successful - as we get an error otherwise if (To == 0 && FileName == "/dev/null") return true; - #if defined HAVE_ZLIB || defined HAVE_BZ2 - if (d != NULL && (d->gz != NULL || d->bz2 != NULL)) + #if defined HAVE_ZLIB || defined HAVE_BZ2 || defined HAVE_LZMA + if (d != NULL && (d->InternalStream() == true + #ifdef HAVE_ZLIB + || d->gz != NULL + #endif + )) return FileFdError("Truncating compressed files is not implemented (%s)", FileName.c_str()); #endif if (ftruncate(iFd,To) != 0) @@@ -1567,11 -1746,7 +1746,7 @@@ unsigned long long FileFd::Tell( // 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 != NULL && (d->pipe == true - #ifdef HAVE_BZ2 - || d->bz2 != NULL - #endif - )) + if (d != NULL && (d->pipe == true || d->InternalStream() == true)) return d->seekpos; off_t Res; @@@ -1646,11 -1821,7 +1821,7 @@@ unsigned long long FileFd::Size( // for compressor pipes st_size is undefined and at 'best' zero, // so we 'read' the content and 'seek' back - see there - if (d != NULL && (d->pipe == true - #ifdef HAVE_BZ2 - || (d->bz2 && size > 0) - #endif - )) + if (d != NULL && (d->pipe == true || (d->InternalStream() == true && size > 0))) { unsigned long long const oldSeek = Tell(); char ignore[1000]; @@@ -1793,7 -1964,13 +1964,13 @@@ bool FileFd::FileFdError(const char *De } /*}}}*/ - gzFile FileFd::gzFd() { return (gzFile) d->gz; } + APT_DEPRECATED gzFile FileFd::gzFd() { + #ifdef HAVE_ZLIB + return d->gz; + #else + return NULL; + #endif + } // Glob - wrapper around "glob()" /*{{{*/ @@@ -1841,14 -2018,3 +2018,14 @@@ std::string GetTempDir( return string(tmpdir); } + +bool Rename(std::string From, std::string To) +{ + if (rename(From.c_str(),To.c_str()) != 0) + { + _error->Error(_("rename failed, %s (%s -> %s)."),strerror(errno), + From.c_str(),To.c_str()); + return false; + } + return true; +} diff --combined apt-pkg/contrib/fileutl.h index f0569b6fd,35f3ab0f4..278a25742 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@@ -27,6 -27,7 +27,7 @@@ #include #include #include + #include #include @@@ -94,7 -95,7 +95,7 @@@ class FileF And as the auto-conversation converts a 'unsigned long *' to a 'bool' instead of 'unsigned long long *' we need to provide this explicitely - otherwise applications magically start to fail… */ - __deprecated bool Read(void *To,unsigned long long Size,unsigned long *Actual) + bool Read(void *To,unsigned long long Size,unsigned long *Actual) APT_DEPRECATED { unsigned long long R; bool const T = Read(To, Size, &R); @@@ -118,7 -119,7 +119,7 @@@ // Simple manipulators inline int Fd() {return iFd;}; inline void Fd(int fd) { OpenDescriptor(fd, ReadWrite);}; - __deprecated gzFile gzFd(); + gzFile gzFd() APT_DEPRECATED APT_PURE; inline bool IsOpen() {return iFd >= 0;}; inline bool Failed() {return (Flags & Fail) == Fail;}; @@@ -152,8 -153,8 +153,8 @@@ bool OpenInternDescriptor(unsigned int const Mode, APT::Configuration::Compressor const &compressor); // private helpers to set Fail flag and call _error->Error - bool FileFdErrno(const char* Function, const char* Description,...) __like_printf(3) __cold; - bool FileFdError(const char* Description,...) __like_printf(2) __cold; + bool FileFdErrno(const char* Function, const char* Description,...) APT_PRINTF(3) APT_COLD; + bool FileFdError(const char* Description,...) APT_PRINTF(2) APT_COLD; }; bool RunScripts(const char *Cnf); @@@ -161,10 -162,9 +162,10 @@@ bool CopyFile(FileFd &From,FileFd &To) int GetLock(std::string File,bool Errors = true); bool FileExists(std::string File); bool RealFileExists(std::string File); - bool DirectoryExists(std::string const &Path) __attrib_const; + bool DirectoryExists(std::string const &Path) APT_CONST; bool CreateDirectory(std::string const &Parent, std::string const &Path); time_t GetModificationTime(std::string const &Path); +bool Rename(std::string From, std::string To); std::string GetTempDir(); diff --combined cmdline/apt-helper.cc index e3652d1ee,37279ec28..2c1107d90 --- a/cmdline/apt-helper.cc +++ b/cmdline/apt-helper.cc @@@ -7,6 -7,7 +7,7 @@@ // Include Files /*{{{*/ #include + #include #include #include #include @@@ -18,22 -19,17 +19,17 @@@ #include #include + #include #include - #include - #include - #include - #include - #include - #include - - + #include + #include + #include #include /*}}}*/ - using namespace std; - bool DoDownloadFile(CommandLine &CmdL) + static bool DoDownloadFile(CommandLine &CmdL) { if (CmdL.FileSize() <= 2) return _error->Error(_("Must specify at least one pair url/filename")); @@@ -44,38 -40,25 +40,28 @@@ Fetcher.Setup(&Stat); std::string download_uri = CmdL.FileList[1]; std::string targetfile = CmdL.FileList[2]; - HashString hash; - new pkgAcqFile(&Fetcher, download_uri, "", 0, "desc", "short-desc", ++ std::string hash; + if (CmdL.FileSize() > 3) - hash = HashString(CmdL.FileList[3]); - new pkgAcqFile(&Fetcher, download_uri, "", 0, "desc", "short-desc", ++ hash = CmdL.FileList[3]; ++ new pkgAcqFile(&Fetcher, download_uri, hash, 0, "desc", "short-desc", "dest-dir-ignored", targetfile); Fetcher.Run(); - if (!FileExists(targetfile)) - { - _error->Error(_("Download Failed")); - return false; - } - if(hash.empty() == false) - { - if(hash.VerifyFile(targetfile) == false) - { - _error->Error(_("HashSum Failed")); - Rename(targetfile, targetfile+".failed"); - return false; - } - } + bool Failed = false; - if (AcquireRun(Fetcher, 0, &Failed, NULL) == false || Failed == false || ++ if (AcquireRun(Fetcher, 0, &Failed, NULL) == false || Failed == true || + FileExists(targetfile) == false) + return _error->Error(_("Download Failed")); return true; } - bool ShowHelp(CommandLine &CmdL) + static bool ShowHelp(CommandLine &) { - ioprintf(cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION, + ioprintf(std::cout,_("%s %s for %s compiled on %s %s\n"),PACKAGE,PACKAGE_VERSION, COMMON_ARCH,__DATE__,__TIME__); if (_config->FindB("version") == true) return true; - cout << + std::cout << _("Usage: apt-helper [options] command\n" " apt-helper [options] download-file uri target-path\n" "\n" diff --combined test/integration/framework index d9bacef83,00c8f3abc..8e401cb5f --- a/test/integration/framework +++ b/test/integration/framework @@@ -90,18 -90,22 +90,22 @@@ msgdone() echo "${CDONE}DONE${CNORMAL}"; fi } - +getaptconfig() { + if [ -f ./aptconfig.conf ]; then + echo "./aptconfig.conf" + elif [ -f ../aptconfig.conf ]; then + echo "../aptconfig.conf" + fi +} runapt() { msgdebug "Executing: ${CCMD}$*${CDEBUG} " local CMD="$1" shift - MALLOC_PERTURB_=21 MALLOC_CHECK_=2 APT_CONFIG="$(getaptconfig)" LD_LIBRARY_PATH=${BUILDDIRECTORY} ${BUILDDIRECTORY}/$CMD "$@" + case $CMD in + sh|aptitude|*/*) ;; + *) CMD="${BUILDDIRECTORY}/$CMD";; + esac - if [ -f ./aptconfig.conf ]; then - MALLOC_PERTURB_=21 MALLOC_CHECK_=2 APT_CONFIG=aptconfig.conf LD_LIBRARY_PATH=${LIBRARYPATH} $CMD "$@" - elif [ -f ../aptconfig.conf ]; then - MALLOC_PERTURB_=21 MALLOC_CHECK_=2 APT_CONFIG=../aptconfig.conf LD_LIBRARY_PATH=${LIBRARYPATH} $CMD "$@" - else - MALLOC_PERTURB_=21 MALLOC_CHECK_=2 LD_LIBRARY_PATH=${LIBRARYPATH} $CMD "$@" - fi ++ MALLOC_PERTURB_=21 MALLOC_CHECK_=2 APT_CONFIG="$(getaptconfig)" LD_LIBRARY_PATH=${BUILDDIRECTORY} $CMD "$@" } aptconfig() { runapt apt-config "$@"; } aptcache() { runapt apt-cache "$@"; } @@@ -111,24 -115,19 +115,19 @@@ aptftparchive() { runapt apt-ftparchiv aptkey() { runapt apt-key "$@"; } aptmark() { runapt apt-mark "$@"; } apt() { runapt apt "$@"; } - apthelper() { - APT_CONFIG="$(getaptconfig)" LD_LIBRARY_PATH=${APTHELPERBINDIR} ${APTHELPERBINDIR}/apt-helper "$@"; - } - aptwebserver() { - LD_LIBRARY_PATH=${APTWEBSERVERBINDIR} ${APTWEBSERVERBINDIR}/aptwebserver "$@"; - } + apthelper() { runapt "${APTHELPERBINDIR}/apt-helper" "$@"; } + aptwebserver() { runapt "${APTWEBSERVERBINDIR}/aptwebserver" "$@"; } + aptitude() { runapt aptitude "$@"; } + dpkg() { command dpkg --root=${TMPWORKINGDIRECTORY}/rootdir --force-not-root --force-bad-path --log=${TMPWORKINGDIRECTORY}/rootdir/var/log/dpkg.log "$@" } - aptitude() { - APT_CONFIG="$(getaptconfig)" LD_LIBRARY_PATH=${BUILDDIRECTORY} command aptitude "$@" + dpkgcheckbuilddeps() { + command dpkg-checkbuilddeps --admindir=${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg "$@" } gdb() { echo "gdb: run »$*«" - APT_CONFIG="$(getaptconfig)" LD_LIBRARY_PATH=${BUILDDIRECTORY} command gdb ${BUILDDIRECTORY}/$1 --args "$@" - } - http() { - LD_LIBRARY_PATH=${BUILDDIRECTORY} ${BUILDDIRECTORY}/methods/http + APT_CONFIG=aptconfig.conf LD_LIBRARY_PATH=${LIBRARYPATH} command gdb ${BUILDDIRECTORY}/$1 --args "$@" } gpg() { # see apt-key for the whole trickery. Setup is done in setupenvironment @@@ -173,6 -172,7 +172,7 @@@ setupenvironment() # allow overriding the default BUILDDIR location BUILDDIRECTORY=${APT_INTEGRATION_TESTS_BUILD_DIR:-"${TESTDIRECTORY}/../../build/bin"} + LIBRARYPATH=${APT_INTEGRATION_TESTS_LIBRARY_PATH:-"${BUILDDIRECTORY}"} METHODSDIR=${APT_INTEGRATION_TESTS_METHODS_DIR:-"${BUILDDIRECTORY}/methods"} APTHELPERBINDIR=${APT_INTEGRATION_TESTS_LIBEXEC_DIR:-"${BUILDDIRECTORY}"} APTWEBSERVERBINDIR=${APT_INTEGRATION_TESTS_WEBSERVER_BIN_DIR:-"${BUILDDIRECTORY}"} @@@ -184,11 -184,12 +184,12 @@@ mkdir rootdir aptarchive keys cd rootdir mkdir -p etc/apt/apt.conf.d etc/apt/sources.list.d etc/apt/trusted.gpg.d etc/apt/preferences.d - mkdir -p var/cache var/lib var/log tmp + mkdir -p var/cache var/lib/apt var/log tmp mkdir -p var/lib/dpkg/info var/lib/dpkg/updates var/lib/dpkg/triggers touch var/lib/dpkg/available mkdir -p usr/lib/apt ln -s ${METHODSDIR} usr/lib/apt/methods + ln -s ${BUILDDIRECTORY}/../../debian/apt.conf.autoremove etc/apt/apt.conf.d/01autoremove cd .. local PACKAGESFILE=$(echo "$(basename $0)" | sed -e 's/^test-/Packages-/' -e 's/^skip-/Packages-/') if [ -f "${TESTDIRECTORY}/${PACKAGESFILE}" ]; then @@@ -217,8 -218,6 +218,6 @@@ echo 'quiet::NoUpdate "true";' >> aptconfig.conf echo "Acquire::https::CaInfo \"${TESTDIR}/apt.pem\";" > rootdir/etc/apt/apt.conf.d/99https echo "Apt::Cmd::Disable-Script-Warning \"1\";" > rootdir/etc/apt/apt.conf.d/apt-binary - export LC_ALL=C.UTF-8 - export PATH="${PATH}:/usr/local/sbin:/usr/sbin:/sbin" configcompression '.' 'gz' #'bz2' 'lzma' 'xz' # gpg needs a trustdb to function, but it can't be invalid (not even empty) @@@ -234,6 -233,12 +233,12 @@@ # newer gpg versions are fine without it, but play it safe for now gpg --quiet --check-trustdb --secret-keyring $SECRETKEYRING --keyring $SECRETKEYRING >/dev/null 2>&1 + # cleanup the environment a bit + export PATH="${PATH}:/usr/local/sbin:/usr/sbin:/sbin" + export LC_ALL=C.UTF-8 + unset LANGUAGE APT_CONFIG + unset GREP_OPTIONS DEB_BUILD_PROFILES + msgdone "info" } @@@ -254,6 -259,10 +259,10 @@@ getarchitectures() echo "$(aptconfig dump | grep APT::Architecture | cut -d'"' -f 2 | sed '/^$/ d' | sort | uniq | tr '\n' ' ')" } + getarchitecturesfromcommalist() { + echo "$1" | sed -e 's#,#\n#g' | sed -e "s/^native\$/$(getarchitecture 'native')/" + } + configarchitecture() { { echo "APT::Architecture \"$(getarchitecture $1)\";" @@@ -427,7 -436,7 +436,7 @@@ Package: $NAME" >> ${BUILDDIR}/debian/c # fi done - for arch in $(echo "$ARCH" | sed -e 's#,#\n#g' | sed -e "s#^native\$#$(getarchitecture 'native')#"); do + for arch in $(getarchitecturesfromcommalist "$ARCH"); do rm -rf ${BUILDDIR}/debian/tmp mkdir -p ${BUILDDIR}/debian/tmp/DEBIAN ${BUILDDIR}/debian/tmp/usr/share/doc/${NAME} ${BUILDDIR}/debian/tmp/usr/bin cp ${BUILDDIR}/debian/copyright ${BUILDDIR}/debian/changelog ${BUILDDIR}/FEATURES ${BUILDDIR}/debian/tmp/usr/share/doc/${NAME} @@@ -582,7 -591,7 +591,7 @@@ insertpackage() something went horribly wrong! They are autogenerated und used only by testcases and surf no other propose…"}" local ARCHS="" - for arch in $(echo "$ARCH" | sed -e 's#,#\n#g' | sed -e "s#^native\$#$(getarchitecture 'native')#"); do + for arch in $(getarchitecturesfromcommalist "$ARCH"); do if [ "$arch" = 'all' -o "$arch" = 'none' ]; then ARCHS="$(getarchitectures)" else @@@ -644,7 -653,7 +653,7 @@@ insertinstalledpackage() local FILE='rootdir/var/lib/dpkg/status' local INFO='rootdir/var/lib/dpkg/info' - for arch in $(echo "$ARCH" | sed -e 's#,#\n#g' | sed -e "s#^native\$#$(getarchitecture 'native')#"); do + for arch in $(getarchitecturesfromcommalist "$ARCH"); do echo "Package: $NAME Status: $STATUS Priority: $PRIORITY @@@ -850,18 -859,16 +859,16 @@@ signreleasefiles() webserverconfig() { msgtest "Set webserver config option '${1}' to" "$2" - downloadfile "http://localhost:8080/_config/set/${1}/${2}" '/dev/null' >/dev/null - local DOWNLOG='download-testfile.log' - rm -f "$DOWNLOG" - local STATUS="${TMPWORKINGDIRECTORY}/rootdir/tmp/webserverconfig.status" - downloadfile "http://localhost:8080/_config/find/aptwebserver::last-status-code" "$STATUS" > "$DOWNLOG" - if [ "$(cat "$STATUS")" = '200' ]; then + local DOWNLOG='rootdir/tmp/download-testfile.log' + local STATUS='rootdir/tmp/webserverconfig.status' + rm -f "$STATUS" "$DOWNLOG" + if downloadfile "http://localhost:8080/_config/set/${1}/${2}" "$STATUS" > "$DOWNLOG"; then msgpass else - cat >&2 "$DOWNLOG" - msgfail "Statuscode was $(cat "$STATUS")" + cat "$DOWNLOG" "$STATUS" + msgfail fi - rm "$STATUS" + testwebserverlaststatuscode '200' } rewritesourceslist() { @@@ -919,23 -926,29 +926,29 @@@ connect = 808 changetocdrom() { mkdir -p rootdir/media/cdrom/.disk local CD="$(readlink -f rootdir/media/cdrom)" - echo "acquire::cdrom::mount \"${CD}\";" > rootdir/etc/apt/apt.conf.d/00cdrom - echo 'acquire::cdrom::autodetect 0;' >> rootdir/etc/apt/apt.conf.d/00cdrom + echo "acquire::cdrom::mount \"${CD}\"; + acquire::cdrom::${CD}/::mount \"mv ${CD}-unmounted ${CD}\"; + acquire::cdrom::${CD}/::umount \"mv ${CD} ${CD}-unmounted\"; + acquire::cdrom::autodetect 0;" > rootdir/etc/apt/apt.conf.d/00cdrom echo -n "$1" > ${CD}/.disk/info if [ ! -d aptarchive/dists ]; then msgdie 'Flat file archive cdroms can not be created currently' return 1 fi - mv aptarchive/dists $CD + mv aptarchive/dists "$CD" ln -s "$(readlink -f ./incoming)" $CD/pool find rootdir/etc/apt/sources.list.d/ -name 'apt-test-*.list' -delete + # start with an unmounted disk + mv "${CD}" "${CD}-unmounted" + # we don't want the disk to be modifiable + addtrap 'prefix' "chmod -f -R +w $PWD/rootdir/media/cdrom/dists/ $PWD/rootdir/media/cdrom-unmounted/dists/ || true;" + chmod -R -w rootdir/media/cdrom-unmounted/dists } downloadfile() { - PROTO="$(echo "$1" | cut -d':' -f 1)" - apthelper -o Acquire::https::CaInfo=${TESTDIR}/apt.pem \ - -o Debug::Acquire::${PROTO}=1 \ - download-file "$1" "$2" 2>&1 + local PROTO="$(echo "$1" | cut -d':' -f 1 )" + apthelper -o Debug::Acquire::${PROTO}=1 \ + download-file "$1" "$2" 2>&1 || true # only if the file exists the download was successful if [ -e "$2" ]; then return 0 @@@ -947,8 -960,8 +960,8 @@@ checkdiff() { local DIFFTEXT="$(command diff -u "$@" | sed -e '/^---/ d' -e '/^+++/ d' -e '/^@@/ d')" if [ -n "$DIFFTEXT" ]; then - echo - echo "$DIFFTEXT" + echo >&2 + echo >&2 "$DIFFTEXT" return 1 else return 0 @@@ -997,11 -1010,17 +1010,17 @@@ testequalor2() shift 2 msgtest "Test for equality OR of" "$*" $* >$COMPAREAGAINST 2>&1 || true - (checkdiff $COMPAREFILE1 $COMPAREAGAINST 1> /dev/null || - checkdiff $COMPAREFILE2 $COMPAREAGAINST 1> /dev/null) && msgpass || - ( echo "\n${CINFO}Diff against OR 1${CNORMAL}" "$(checkdiff $COMPAREFILE1 $COMPAREAGAINST)" \ - "\n${CINFO}Diff against OR 2${CNORMAL}" "$(checkdiff $COMPAREFILE2 $COMPAREAGAINST)" && - msgfail ) + if checkdiff $COMPAREFILE1 $COMPAREAGAINST >/dev/null 2>&1 || \ + checkdiff $COMPAREFILE2 $COMPAREAGAINST >/dev/null 2>&1 + then + msgpass + else + echo -n "\n${CINFO}Diff against OR 1${CNORMAL}" + checkdiff $COMPAREFILE1 $COMPAREAGAINST || true + echo -n "${CINFO}Diff against OR 2${CNORMAL}" + checkdiff $COMPAREFILE2 $COMPAREAGAINST || true + msgfail + fi } testshowvirtual() { @@@ -1027,24 -1046,24 +1046,24 @@@ testnopackage() msgtest "Test for non-existent packages" "apt-cache show $*" local SHOWPKG="$(aptcache show "$@" 2>&1 | grep '^Package: ')" if [ -n "$SHOWPKG" ]; then - echo - echo "$SHOWPKG" + echo >&2 + echo >&2 "$SHOWPKG" msgfail - return 1 + else + msgpass fi - msgpass } testdpkginstalled() { msgtest "Test for correctly installed package(s) with" "dpkg -l $*" local PKGS="$(dpkg -l "$@" 2>/dev/null | grep '^i' | wc -l)" if [ "$PKGS" != $# ]; then - echo $PKGS - dpkg -l "$@" | grep '^[a-z]' + echo >&2 $PKGS + dpkg -l "$@" | grep '^[a-z]' >&2 msgfail - return 1 + else + msgpass fi - msgpass } testdpkgnotinstalled() { @@@ -1052,11 -1071,11 +1071,11 @@@ local PKGS="$(dpkg -l "$@" 2> /dev/null | grep '^i' | wc -l)" if [ "$PKGS" != 0 ]; then echo - dpkg -l "$@" | grep '^[a-z]' + dpkg -l "$@" | grep '^[a-z]' >&2 msgfail - return 1 + else + msgpass fi - msgpass } testmarkedauto() { @@@ -1081,8 -1100,8 +1100,8 @@@ testsuccess() if $@ >${OUTPUT} 2>&1; then msgpass else - echo - cat $OUTPUT + echo >&2 + cat >&2 $OUTPUT msgfail fi } @@@ -1095,14 -1114,35 +1114,35 @@@ testfailure() fi local OUTPUT="${TMPWORKINGDIRECTORY}/rootdir/tmp/testfailure.output" if $@ >${OUTPUT} 2>&1; then - echo - cat $OUTPUT + echo >&2 + cat >&2 $OUTPUT msgfail else msgpass fi } + testwebserverlaststatuscode() { + local DOWNLOG='rootdir/tmp/webserverstatus-testfile.log' + local STATUS='rootdir/tmp/webserverstatus-statusfile.log' + rm -f "$DOWNLOG" "$STATUS" + msgtest 'Test last status code from the webserver was' "$1" + downloadfile "http://localhost:8080/_config/find/aptwebserver::last-status-code" "$STATUS" > "$DOWNLOG" + if [ "$(cat "$STATUS")" = "$1" ]; then + msgpass + else + echo >&2 + if [ -n "$2" ]; then + shift + echo >&2 '#### Additionally provided output files contain:' + cat >&2 "$@" + fi + echo >&2 '#### Download log of the status code:' + cat >&2 "$DOWNLOG" + msgfail "Status was $(cat "$STATUS")" + fi + } + pause() { echo "STOPPED execution. Press enter to continue" local IGNORE diff --combined test/integration/test-apt-helper index 37ed95181,000000000..6505b5956 mode 100755,000000..100755 --- a/test/integration/test-apt-helper +++ b/test/integration/test-apt-helper @@@ -1,37 -1,0 +1,39 @@@ +#!/bin/sh +set -e + +TESTDIR=$(readlink -f $(dirname $0)) +. $TESTDIR/framework + +setupenvironment +configarchitecture "i386" + +changetohttpswebserver + +echo "foo" > aptarchive/foo + +msgtest 'apt-file download-file md5sum' +apthelper -qq download-file http://localhost:8080/foo foo2 MD5Sum:d3b07384d113edec49eaa6238ad5ff00 && msgpass || msgfail +testfileequal foo2 'foo' + +msgtest 'apt-file download-file sha1' +apthelper -qq download-file http://localhost:8080/foo foo1 SHA1:f1d2d2f924e986ac86fdf7b36c94bcdf32beec15 && msgpass || msgfail +testfileequal foo1 'foo' + +msgtest 'apt-file download-file sha256' +apthelper -qq download-file http://localhost:8080/foo foo3 SHA256:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c && msgpass || msgfail +testfileequal foo3 'foo' + +msgtest 'apt-file download-file no-hash' +apthelper -qq download-file http://localhost:8080/foo foo4 && msgpass || msgfail +testfileequal foo4 'foo' + +msgtest 'apt-file download-file wrong hash' +if ! apthelper -qq download-file http://localhost:8080/foo foo5 MD5Sum:aabbcc 2>&1 2> download.stderr; then + msgpass +else + msgfail +fi - testfileequal download.stderr 'E: HashSum Failed' - testfileequal foo5.failed 'foo' ++testfileequal download.stderr 'E: Failed to fetch http://localhost:8080/foo Hash Sum mismatch ++ ++E: Download Failed' ++testfileequal foo5.FAILED 'foo'