From 2d71f8c24d490b5a3773821264124f0ed5c9a9d2 Mon Sep 17 00:00:00 2001 From: Jaywalker Date: Tue, 6 Feb 2018 23:51:41 -0600 Subject: Fixed system() using coolstar's patch and added other required patches --- apt-pkg/contrib/fileutl.cc | 165 +++++++++++++++++++++++++++++++++++++++++- apt-pkg/contrib/fileutl.h | 2 + apt-pkg/contrib/gpgv.cc | 29 +++++++- apt-pkg/contrib/srvrec.cc | 1 + apt-pkg/contrib/string_view.h | 1 + apt-pkg/deb/deblistparser.cc | 1 + apt-pkg/deb/deblistparser.h | 2 + apt-pkg/deb/dpkgpm.cc | 4 +- apt-pkg/tagfile.cc | 8 ++ apt-pkg/tagfile.h | 3 +- apt-private/private-source.cc | 4 +- ftparchive/byhash.cc | 2 + ftparchive/cachedb.cc | 1 + 13 files changed, 216 insertions(+), 7 deletions(-) diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index dd36ffa79..e3fb1cc90 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -74,6 +75,14 @@ #endif #include + +//posix spawn +#include +#include +#include +#include +#include + /*}}}*/ using namespace std; @@ -81,6 +90,8 @@ using namespace std; /* Should be a multiple of the common page size (4096) */ static constexpr unsigned long long APT_BUFFER_SIZE = 64 * 1024; +extern char **environ; + // RunScripts - Run a set of scripts from a configuration subtree /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -119,7 +130,7 @@ bool RunScripts(const char *Cnf) std::clog << "Running external script: '" << Opts->Value << "'" << std::endl; - if (system(Opts->Value.c_str()) != 0) + if (RunCmd(Opts->Value.c_str()) != 0) _exit(100+Count); } _exit(0); @@ -154,6 +165,158 @@ bool RunScripts(const char *Cnf) return true; } + +#define PROC_PIDPATHINFO_MAXSIZE (1024) +static int file_exist(const char *filename) { + struct stat buffer; + int r = stat(filename, &buffer); + return (r == 0); +} + +static char *searchpath(const char *binaryname){ + if (strstr(binaryname, "/") != NULL){ + if (file_exist(binaryname)){ + char *foundpath = malloc((strlen(binaryname) + 1) * (sizeof(char))); + strcpy(foundpath, binaryname); + return foundpath; + } else { + return NULL + } + } + + char *pathvar = getenv("PATH"); + + char *dir = strtok(pathvar,":"); + while (dir != NULL){ + char searchpth[PROC_PIDPATHINFO_MAXSIZE]; + strcpy(searchpth, dir); + strcat(searchpth, "/"); + strcat(searchpth, binaryname); + + if (file_exist(searchpth)){ + char *foundpath = malloc((strlen(searchpth) + 1) * (sizeof(char))); + strcpy(foundpath, searchpth); + return foundpath; + } + + dir = strtok(NULL, ":"); + } + return NULL; +} + +static bool isShellScript(const char *path){ + FILE *file = fopen(path, "r"); + uint8_t header[2]; + if (fread(header, sizeof(uint8_t), 2, file) == 2){ + if (header[0] == '#' && header[1] == '!'){ + fclose(file); + return true; + } + } + fclose(file); + return false; +} + +static char *getInterpreter(char *path){ + FILE *file = fopen(path, "r"); + char *interpreterLine = NULL; + unsigned long lineSize = 0; + getline(&interpreterLine, &lineSize, file); + + char *rawInterpreter = (interpreterLine+2); + rawInterpreter = strtok(rawInterpreter, " "); + rawInterpreter = strtok(rawInterpreter, "\n"); + + char *interpreter = malloc((strlen(rawInterpreter)+1) * sizeof(char)); + strcpy(interpreter, rawInterpreter); + + free(interpreterLine); + fclose(file); + return interpreter; +} + +static char *fixedCmd(const char *cmdStr){ + char *cmdCpy = malloc((strlen(cmdStr)+1) * sizeof(char)); + strcpy(cmdCpy, cmdStr); + + char *cmd = strtok(cmdCpy, " "); + + uint8_t size = strlen(cmd) + 1; + + char *args = cmdCpy + (size + 1); + if ((strlen(cmdStr) - strlen(cmd)) == 0) + args = NULL; + + char *abs_path = searchpath(cmd); + if (abs_path){ + bool isScript = isShellScript(abs_path); + if (isScript){ + char *interpreter = getInterpreter(abs_path); + + uint8_t commandSize = strlen(interpreter) + 1 + strlen(abs_path); + + if (args){ + commandSize += 1 + strlen(args); + } + + char *rawCommand = malloc(sizeof(char) * (commandSize + 1)); + strcpy(rawCommand, interpreter); + strcat(rawCommand, " "); + strcat(rawCommand, abs_path); + + if (args){ + strcat(rawCommand, " "); + strcat(rawCommand, args); + } + rawCommand[(commandSize)+1] = "\0"; + + free(interpreter); + free(abs_path); + free(cmdCpy); + + return rawCommand; + } else { + uint8_t commandSize = strlen(abs_path); + + if (args){ + commandSize += 1 + strlen(args); + } + + char *rawCommand = malloc(sizeof(char) * (commandSize + 1)); + strcat(rawCommand, abs_path); + + if (args){ + strcat(rawCommand, " "); + strcat(rawCommand, args); + } + rawCommand[(commandSize)+1] = "\0"; + + free(abs_path); + free(cmdCpy); + + return rawCommand; + } + } + return cmdCpy; +} + +int RunCmd(const char *cmd) { + pid_t pid; + char *rawCmd = fixedCmd(cmd); + char *argv[] = {"sh", "-c", (char*)rawCmd, NULL}; + int status; + status = posix_spawn(&pid, "/bin/sh", NULL, NULL, argv, environ); + if (status == 0) { + if (waitpid(pid, &status, 0) == -1) { + perror("waitpid"); + } + } else { + printf("posix_spawn: %s\n", strerror(status)); + } + free(rawCmd); + return status; +} + /*}}}*/ // CopyFile - Buffered copy of a file /*{{{*/ diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index dddeb70f5..932538206 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -158,6 +158,8 @@ class FileFd APT_HIDDEN bool FileFdError(const char* Description,...) APT_PRINTF(2) APT_COLD; }; + +int RunCmd(const char *Cmd); bool RunScripts(const char *Cnf); bool CopyFile(FileFd &From,FileFd &To); bool RemoveFile(char const * const Function, std::string const &FileName); diff --git a/apt-pkg/contrib/gpgv.cc b/apt-pkg/contrib/gpgv.cc index 856d56bc1..fa1055556 100644 --- a/apt-pkg/contrib/gpgv.cc +++ b/apt-pkg/contrib/gpgv.cc @@ -252,7 +252,34 @@ void ExecGPGV(std::string const &File, std::string const &FileGPG, { if (statusfd != -1) dup2(fd[1], statusfd); - execvp(Args[0], (char **) &Args[0]); + //I don't really C++, so I hope this is the best way to make a std::vector into a space separated C-string. + char *fullCmd = NULL; + char *tmpCmd = NULL; + bool firstTime = true; + int size = 0; + for (std::vector::const_iterator a = Args.begin(); a != Args.end(); ++a) { + size = strlen(*a) + 1; //Plus one for \0 + if (fullCmd != NULL) { + size += strlen(fullCmd) + 1; //Plus one for space + if (tmpCmd != NULL) + free(tmpCmd); + tmpCmd = (char *)malloc(sizeof(char) * (strlen(fullCmd) + 1)); + strcpy(tmpCmd, fullCmd); + free(fullCmd); + } + fullCmd = (char *)malloc(sizeof(char) * size); + if (tmpCmd == NULL) + strcpy(fullCmd, *a); + else + sprintf(fullCmd, "%s %s\0", tmpCmd, *a); + } + if (tmpCmd != NULL) + free(tmpCmd); + if (fullCmd != NULL) { + RunCmd(fullCmd); + free(fullCmd); + } + //execvp(Args[0], (char **) &Args[0]); apt_error(std::cerr, statusfd, fd, "Couldn't execute %s to check %s", Args[0], File.c_str()); local_exit(EINTERNAL); } diff --git a/apt-pkg/contrib/srvrec.cc b/apt-pkg/contrib/srvrec.cc index cafee1acf..f2c45a458 100644 --- a/apt-pkg/contrib/srvrec.cc +++ b/apt-pkg/contrib/srvrec.cc @@ -12,6 +12,7 @@ #include #include +#include #include #include diff --git a/apt-pkg/contrib/string_view.h b/apt-pkg/contrib/string_view.h index e0aff3dca..52ad71d5c 100644 --- a/apt-pkg/contrib/string_view.h +++ b/apt-pkg/contrib/string_view.h @@ -14,6 +14,7 @@ #include #include #include +#include namespace APT { diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc index 23048008b..17c283615 100644 --- a/apt-pkg/deb/deblistparser.cc +++ b/apt-pkg/deb/deblistparser.cc @@ -63,6 +63,7 @@ debListParser::debListParser(FileFd *File) : else forceEssential.emplace_back("apt"); forceImportant = _config->FindVector("pkgCacheGen::ForceImportant"); + Arch = _config->Find("APT::architecture"); } /*}}}*/ // ListParser::Package - Return the package name /*{{{*/ diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h index 840b48b8d..733ea0542 100644 --- a/apt-pkg/deb/deblistparser.h +++ b/apt-pkg/deb/deblistparser.h @@ -52,6 +52,8 @@ class APT_HIDDEN debListParser : public pkgCacheListParser pkgTagSection Section; map_filesize_t iOffset; + std::string Arch; + virtual bool ParseStatus(pkgCache::PkgIterator &Pkg,pkgCache::VerIterator &Ver); bool ParseDepends(pkgCache::VerIterator &Ver, pkgTagSection::Key Key, unsigned int Type); diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index bdef7b516..45ed66996 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1698,7 +1698,7 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) bool dpkgMultiArch = debSystem::SupportsMultiArch(); // start pty magic before the loop - StartPtyMagic(); + //StartPtyMagic(); or not... // Tell the progress that its starting and fork dpkg d->progress->Start(d->master); @@ -2098,7 +2098,7 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) } } // dpkg is done at this point - StopPtyMagic(); + //StopPtyMagic(); CloseLog(); if (d->dpkg_error.empty() == false) diff --git a/apt-pkg/tagfile.cc b/apt-pkg/tagfile.cc index 1aa67cc67..4c2a8b6b8 100644 --- a/apt-pkg/tagfile.cc +++ b/apt-pkg/tagfile.cc @@ -335,6 +335,14 @@ void pkgTagSection::TrimRecord(bool BeforeRecord, const char*& End, bool Support } } /*}}}*/ +// TagSection::Trim - Trim off any trailing garbage /*{{{*/ +// --------------------------------------------------------------------- +/* There should be exactly 1 newline at the end of the buffer, no more. */ +void pkgTagSection::Trim() +{ + for (; Stop > Section + 2 && (Stop[-2] == '\n' || Stop[-2] == '\r'); Stop--); +} + // TagSection::Exists - return True if a tag exists /*{{{*/ bool pkgTagSection::Exists(StringView Tag) const { diff --git a/apt-pkg/tagfile.h b/apt-pkg/tagfile.h index bd3b4d1ea..a788e1044 100644 --- a/apt-pkg/tagfile.h +++ b/apt-pkg/tagfile.h @@ -138,9 +138,10 @@ class pkgTagSection * @return \b true if section end was found, \b false otherwise. * Beware that internal state will be inconsistent if \b false is returned! */ - APT_MUSTCHECK bool Scan(const char *Start, unsigned long MaxLength, bool const SupportComments); + APT_MUSTCHECK bool Scan(const char *Start, unsigned long MaxLength, bool const SupportComments = true); inline unsigned long size() const {return Stop - Section;}; + void Trim(); void TrimRecord(bool BeforeRecord, const char* &End, bool SupportComments); /** \brief amount of Tags in the current section diff --git a/apt-private/private-source.cc b/apt-private/private-source.cc index 1e819a668..9e7951ed2 100644 --- a/apt-private/private-source.cc +++ b/apt-private/private-source.cc @@ -533,7 +533,7 @@ bool DoSource(CommandLine &CmdL) strprintf(S, "%s %s %s", _config->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(), sourceopts.c_str(), Dsc[I].Dsc.c_str()); - if (system(S.c_str()) != 0) + if (RunCmd(S.c_str()) != 0) { fprintf(stderr, _("Unpack command '%s' failed.\n"), S.c_str()); fprintf(stderr, _("Check if the 'dpkg-dev' package is installed.\n")); @@ -562,7 +562,7 @@ bool DoSource(CommandLine &CmdL) _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(), buildopts.c_str()); - if (system(S.c_str()) != 0) + if (RunCmd(S.c_str()) != 0) { fprintf(stderr, _("Build command '%s' failed.\n"), S.c_str()); _exit(1); diff --git a/ftparchive/byhash.cc b/ftparchive/byhash.cc index 354d089c3..358fd27b4 100644 --- a/ftparchive/byhash.cc +++ b/ftparchive/byhash.cc @@ -17,6 +17,8 @@ #include #include +#define st_mtim st_mtimespec + #include #include #include "byhash.h" diff --git a/ftparchive/cachedb.cc b/ftparchive/cachedb.cc index 868029abd..930bb5f94 100644 --- a/ftparchive/cachedb.cc +++ b/ftparchive/cachedb.cc @@ -22,6 +22,7 @@ #include #include #include +#include #include // htonl, etc #include -- cgit v1.2.3