X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/410ea6525d613fe91029d5a6526254739fc5880b..8d6d3f00b14217e69ecabd68379b1e29bf4a3ccd:/apt-pkg/deb/debsystem.cc?ds=sidebyside diff --git a/apt-pkg/deb/debsystem.cc b/apt-pkg/deb/debsystem.cc index 7644bc66b..5353761fc 100644 --- a/apt-pkg/deb/debsystem.cc +++ b/apt-pkg/deb/debsystem.cc @@ -10,6 +10,8 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ +#include + #include #include #include @@ -17,16 +19,32 @@ #include #include #include -#include -#include +#include +#include + +#include + +#include +#include +#include +#include +#include #include #include #include +#include +#include +#include +#include + +#include /*}}}*/ +using std::string; + debSystem debSys; -class debSystemPrivate { +class APT_HIDDEN debSystemPrivate { public: debSystemPrivate() : LockFD(-1), LockCount(0), StatusFile(0) { @@ -41,11 +59,8 @@ public: // System::debSystem - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ -debSystem::debSystem() +debSystem::debSystem() : pkgSystem("Debian dpkg interface", &debVS), d(new debSystemPrivate()) { - d = new debSystemPrivate(); - Label = "Debian dpkg interface"; - VS = &debVS; } /*}}}*/ // System::~debSystem - Destructor /*{{{*/ @@ -188,9 +203,9 @@ bool debSystem::Initialize(Configuration &Cnf) /*}}}*/ // System::ArchiveSupported - Is a file format supported /*{{{*/ // --------------------------------------------------------------------- -/* The standard name for a deb is 'deb'.. There are no seperate versions +/* The standard name for a deb is 'deb'.. There are no separate versions of .deb to worry about.. */ -bool debSystem::ArchiveSupported(const char *Type) +APT_PURE bool debSystem::ArchiveSupported(const char *Type) { if (strcmp(Type,"deb") == 0) return true; @@ -216,7 +231,7 @@ signed debSystem::Score(Configuration const &Cnf) // System::AddStatusFiles - Register the status files /*{{{*/ // --------------------------------------------------------------------- /* */ -bool debSystem::AddStatusFiles(vector &List) +bool debSystem::AddStatusFiles(std::vector &List) { if (d->StatusFile == 0) d->StatusFile = new debStatusIndex(_config->FindFile("Dir::State::status")); @@ -241,3 +256,90 @@ bool debSystem::FindIndex(pkgCache::PkgFileIterator File, return false; } /*}}}*/ + +std::string debSystem::GetDpkgExecutable() /*{{{*/ +{ + string Tmp = _config->Find("Dir::Bin::dpkg","dpkg"); + string const dpkgChrootDir = _config->FindDir("DPkg::Chroot-Directory", "/"); + size_t dpkgChrootLen = dpkgChrootDir.length(); + if (dpkgChrootDir != "/" && Tmp.find(dpkgChrootDir) == 0) + { + if (dpkgChrootDir[dpkgChrootLen - 1] == '/') + --dpkgChrootLen; + Tmp = Tmp.substr(dpkgChrootLen); + } + return Tmp; +} + /*}}}*/ +std::vector debSystem::GetDpkgBaseCommand() /*{{{*/ +{ + // Generate the base argument list for dpkg + std::vector Args = { GetDpkgExecutable() }; + // Stick in any custom dpkg options + Configuration::Item const *Opts = _config->Tree("DPkg::Options"); + if (Opts != 0) + { + Opts = Opts->Child; + for (; Opts != 0; Opts = Opts->Next) + { + if (Opts->Value.empty() == true) + continue; + Args.push_back(Opts->Value); + } + } + return Args; +} + /*}}}*/ +void debSystem::DpkgChrootDirectory() /*{{{*/ +{ + std::string const chrootDir = _config->FindDir("DPkg::Chroot-Directory"); + if (chrootDir == "/") + return; + std::cerr << "Chrooting into " << chrootDir << std::endl; + if (chroot(chrootDir.c_str()) != 0) + _exit(100); + if (chdir("/") != 0) + _exit(100); +} + /*}}}*/ +bool debSystem::SupportsMultiArch() /*{{{*/ +{ + // Generate the base argument list for dpkg + std::vector const Args = GetDpkgBaseCommand(); + std::vector cArgs(Args.size(), NULL); + std::transform(Args.begin(), Args.end(), cArgs.begin(), [](std::string const &s) { return s.c_str(); }); + + // we need to detect if we can qualify packages with the architecture or not + cArgs.push_back("--assert-multi-arch"); + cArgs.push_back(NULL); + + pid_t dpkgAssertMultiArch = ExecFork(); + if (dpkgAssertMultiArch == 0) + { + DpkgChrootDirectory(); + // redirect everything to the ultimate sink as we only need the exit-status + int const nullfd = open("/dev/null", O_RDONLY); + dup2(nullfd, STDIN_FILENO); + dup2(nullfd, STDOUT_FILENO); + dup2(nullfd, STDERR_FILENO); + execvp(cArgs[0], (char**) &cArgs[0]); + _error->WarningE("dpkgGo", "Can't detect if dpkg supports multi-arch!"); + _exit(2); + } + + if (dpkgAssertMultiArch > 0) + { + int Status = 0; + while (waitpid(dpkgAssertMultiArch, &Status, 0) != dpkgAssertMultiArch) + { + if (errno == EINTR) + continue; + _error->WarningE("dpkgGo", _("Waited for %s but it wasn't there"), "dpkg --assert-multi-arch"); + break; + } + if (WIFEXITED(Status) == true && WEXITSTATUS(Status) == 0) + return true; + } + return false; +} + /*}}}*/